Простое has_many: через ассоциацию - PullRequest
0 голосов
/ 20 февраля 2012

Довольно простая настройка.Я хочу убедиться, что мое понимание ORM правильное.

class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, through => memberships
end

class Group < ActiveRecord::Base
  has_many :memberships
  has_many :users, through => memberships
end

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

Теперь, когда пользователь создает группу, я хочу, чтобы запись членства в таблице ссылок была заполнена.Это должно быть атомное (транзакция).

class GroupsController < ApplicationController
  def create

    @group = current_user.groups.build(params[:group])

    if @group.save
      flash[:notice] = "Group has been created."
      redirect_to @group
    else
      flash[:alert] = "Group has not been created."
      render :action => "new"
    end
  end
end

Это не работает.Группа сохраняется, но в таблице ссылок не создается запись о членстве.Однако использование Create vs build работает.Вот как это должно работать?

Какой здесь лучший подход?

1 Ответ

0 голосов
/ 20 февраля 2012

Это поведение является намеренным.Как вы упомянули, вы можете либо сделать @group = current_user.groups.create(params[:group]).

, либо добавить дополнительный оператор для создания записи в таблице модели соединения в виде:

@group = current_user.groups.build(params[:group])
if @group.save
   @group.memberships.create(:user_id => current_user)
   # redirect and notify 

Ну, причина в том, чтопростое построение @group и его сохранение не добавляет дополнительную запись в таблицу соединений.

Фактически, в этом случае @group = current_user.groups.build(params[:group]) несколько напоминает @group = Group.new(params[:group]).Разница в том, что в первом случае current_user.groups будет содержать @group (вы можете попробовать это в Groups#create перед перенаправлением), но выполнение current_user.reload с последующим current_user.groups даст [].

Лучший способ сделать это несколько похож на ваш подход.Выполните простое действие создания как:

def create
   @group = Group.new(params[:group])
   # if else for save and redirect

Однако, чтобы это работало, хэш параметров, отправленный в Groups#create, должен включать user_ids как:

"group"=>{"name"=>"new group", "user_ids"=>["1", "2", "3"]}, "commit"=>"Create Group"

Возможно, именно поэтомупочему @ bruno077 просил вас вставить код вашего представления, чтобы получить представление о передаваемых параметрах user_ids.

Итак, если новая форма группы содержит поля для выбора нескольких пользователей, то ее простое действие create какпоказано выше (из-за параметров user_ids).Но если у вас есть новая групповая форма без опций для выбора пользователей, то вам лучше использовать первый вариант (тот, который использует create).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...