【问题标题】:Rails 3: Has_many through and MeRails 3:Has_many 和我
【发布时间】:2012-11-28 00:43:09
【问题描述】:

我对 Rails 还很陌生,我得到了这段代码,但我认为我正在阻止它执行 Rails 的一些魔力:

目标:创建一个cause,并通过build 方法和Cause_User_Membership 表中的has_many :through 关联让创建者成为成员。

问题:我已经通过创建cause 然后“手动”创建会员资格来实现它。有没有办法在创建cause 时自动创建Cause_User_Membership 关系?

Cause_Controller.rb

def create
@cause = current_user.causes.build(params[:cause].merge :created_by => current_user.id)

respond_to do |format|
  if @cause.save 
    @membership = current_user.cause_user_memberships.build(:cause_id => @cause.id)
    @membership.save
    format.json { render :json => {current_user: current_user, results: @cause}}
  else
    format.json { render :json => {Message: "You messed up"}}
  end
end
end

User.rb (sn-p)

has_many :cause_user_memberships
has_many :causes, :through => :cause_user_memberships

Cause.rb

attr_accessible :title, :location, :description,...
has_many :cause_user_memberships
has_many :users, :through => :cause_user_memberships

Cause_User_Membership.rb

    # == Schema Information
#
# Table name: cause_user_memberships
#
#  id         :integer          not null, primary key
#  user_id    :integer          not null
#  cause_id   :integer          not null
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class CauseUserMembership < ActiveRecord::Base
  attr_accessible :cause_id, :user_id

  belongs_to :user #, :class_name => "User", :foreign_key => "user_id" 
  belongs_to :cause #, :class_name => "Cause", :foreign_key => "cause_id"

end

【问题讨论】:

  • 如果只删除设置@membership 的两行会怎样?我认为当您在关联上使用build 时应该自动创建该记录。
  • 它不会创建它,这就是我的头撞墙的原因 :) 感谢您回复我!
  • 感谢您的链接,但所有信息似乎都是 Rails 3 之前的信息。有没有人看到有关如何解决此问题的最新信息?谢谢
  • 如果没有其他人回答,我今天晚些时候再看看。

标签: ruby-on-rails-3 activerecord associations has-many-through


【解决方案1】:

更新:

我发现了一种使用accepts_nested_attributes_for 更“神奇”的方法来做到这一点。首先,在CauseUserMembership 模型中添加一行:

class CauseUserMembership < ActiveRecord::Base
  attr_accessible :cause_id, :user_id

  belongs_to :user
  belongs_to :cause 

  accepts_nested_attributes_for :cause

通过该更改,您可以执行以下操作:

def create
  @membership = current_user.memberships.build
  @membership.cause = Cause.new(params[:cause].merge(:created_by => current_user.id)

  respond_to do |format|
    if @membership.save
      ...

因为您已告诉 rails 接受 CauseUserMembership 上的 cause 关联的嵌套属性,所以它会在保存成员资格本身时保存您分配给 @membership.cause 的新原因。因此,您可以一次保存原因记录和成员记录,而不是单独保存。

原答案:

我认为您所做的几乎是正确的方法。它可以简化一点:您不需要从current_user 构建cause,您可以使用newcausecurrent_user 上的:through 关联在您创建@ 时设置987654336@).

就这样(我只改了create的第一行):

def create
  @cause = Cause.new(params[:cause].merge(:created_by => current_user.id))

  respond_to do |format|
    if @cause.save
      @membership = current_user.cause_user_memberships.build(:cause_id => @cause.id)
      @membership.save
      ...

另见:Many-to-Many through association Build/Create properties in Rails app

【讨论】:

  • 太好了,谢谢!没有“神奇”地完成这件事有什么特别的原因吗?
  • 我已经用一种更“神奇”的方式更新了我的答案。看看你的想法。
  • 谢谢,新方法也有效。我尝试做几乎相同的事情,因为接受会员属性,但无法使其正常工作。在您列出的两种方法中,哪种方法被认为是更好的做法?
  • 两者都不是真的更好,它们只是有点不同。使用 accepts_nested_attributes_for,您可以通过父 (@membership) 更新关联记录(在本例中为 @membership.cause)上的其他属性,这可能有用也可能没用。例如,您可以拥有一个包含成员资格和关联原因的嵌套数据的表单,并通过仅使用 @membership.update_attributes(params[:membership]) 的成员资格更新关联数据。
猜你喜欢
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多