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 модель, а не в двух местах.

Другие вопросы по тегам