Как получить доступ к модели соединения в has_many: через отношения - PullRequest
0 голосов
/ 17 февраля 2010

У меня типичное отношение «многие ко многим» с использованием has_many => :through, как подробно описано ниже.

class member
  has_many member_roles
  has_many roles, :through => :member_roles
end

class role
  has_many member_roles
  has_man members, :through => :member_roles
end

class member_role
  belongs_to :member
  belongs_to :role
  # has following fields: member_id, role_id, scope, sport_id
end

То, что я пытаюсь сделать здесь, это позволить членам назначаться на роли. Каждая роль члена имеет область, которая по умолчанию установлена ​​на «Все», но при желании может быть установлена ​​на «Спорт». Если область действия установлена ​​на спорт, то мы также фиксируем sport_id, что позволяет нам ограничить оценку этой роли определенным видом спорта (т. Е. Может управлять только командами этого вида спорта, а не командами каждого вида спорта). Звучит достаточно просто.

Я настроил свое update_member_roles действие примерно так:

def update

  # Assume we passing a param like: params[:member][:roles]
  # as an array of hashes consisting of :role_id and if set, :sport_id

  roles = (params[:member] ||= {}).delete "roles"
  @member.roles = Role.find_all_by_id(roles.map{|r| r["role_id"]})
  if @member.update_attributes params[:member]
    flash[:notice] = "Roles successfully updated."
    redirect_to member_path(@member)
  else
    render :action => "edit"
  end
end

Вышеописанное работает достаточно хорошо, оно очень хорошо устанавливает соответствующие member_roles ... но так как я работаю над моделью Role, а не моделью MemberRole, я как бы застрял в том, как получить доступ к модели присоединения установите: scope и: sport_id.

Любые указатели здесь будут высоко оценены.

Ответы [ 2 ]

1 голос
/ 18 февраля 2010

Вы должны использовать ассоциацию member_roles вместо roles ассоциации.

  def update
    # The role hash should contain :role_id, :scope and if set, :sport_id
    roles = ((params[:member] ||= {}).delete "roles") || []
    MemberRole.transaction do 

      # Next line will associate the :sport_id and :scope to member_roles
      # EDIT: Changed the code to flush old roles.
      @member.member_roles = roles.collect{|r| MemberRole.new(r)}

      # Next line will save the member attributes and member_roles in one TX
      if @member.update_attributes params[:member]
        # some code
      else
        # some code
      end
    end
  end

Убедитесь, что вы заключили все в одну транзакцию.

Другая возможность - использовать accepts_nested_attributes_for для member_roles ассоциации.

0 голосов
/ 17 февраля 2010

Звучит так, как будто вы должны использовать вложенные атрибуты:

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