Rails множественное назначение
Дано
Пользователь:
class User < ActiveRecord::Base
has_many :discussions
has_many :posts
end
Обсуждение:
class Discussion < ActiveRecord::Base
belongs_to :user
has_many :posts
end
Сообщения:
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :discussion
end
В настоящее время я инициализирую сообщения в контроллере через
@post = current_user.posts.build(params[:post])
Мой вопрос: как мне установить / сохранить / отредактировать модель @post так, чтобы также была установлена связь между публикацией и обсуждением?
1 ответ
Сохраняйте и редактируйте обсуждения вместе с постом
Существующее обсуждение
Чтобы связать создаваемую запись с существующей дискуссией, просто объедините идентификатор с параметрами записи.
@post = current_user.posts.build(
params[:post].merge(
:discussion_id => existing_discussion.id
)
У вас должен быть скрытый вход для идентификатора обсуждения в форме для @post
поэтому ассоциация спасена.
Новое обсуждение
Если вы хотите построить новое обсуждение вместе с каждым постом и управлять его атрибутами через форму, используйте accepts_nested_attributes
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :discussion
accepts_nested_attributes_for :discussion
end
Затем вы должны построить обсуждение в контроллере сbuild_discussion
после того, как вы создали пост
@post.build_discussion
И в вашей форме вы можете включить вложенные поля для обсуждений
form_for @post do |f|
f.fields_for :discussion do |df|
...etc
Это создаст обсуждение вместе с постом. Чтобы узнать больше о вложенных атрибутах, посмотрите этот отличный Railscast
Лучшие отношения
Кроме того, вы можете использовать :through
вариант has_many
ассоциация для более последовательной реляционной установки:
class User < ActiveRecord::Base
has_many :posts
has_many :discussions, :through => :posts, :source => :discussion
end
class Discussion < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :user
belongs_to :discussion
end
Таким образом, отношение пользователя к обсуждению поддерживается только в Post
модель, а не в двух местах.