rails3:<object> .save!不会在habtm </object>中关联新子项

时间:2012-03-16 14:09:38

标签: ruby-on-rails save new-operator has-and-belongs-to-many

我有两个通过habtm关联的模型:

class Participant < ActiveRecord::Base
 has_and_belongs_to_many :reports
end

class Report < ActiveRecord::Base
 has_and_belongs_to_many :participants
end

在更新单个报告的视图中,可以输入参与者的电子邮件地址,以将此参与者与当前报告相关联。
问题:通过删除表单中的电子邮件地址来删除参与者工作正常但是关联新参与者不起作用(无论参与者本人是否已经存在)。
这是更新报告的代码:

num_of_participants = @report.participants.length
count = 0
num_of_participants.times do
 if @report.participants[count].email.empty?
  @report.participants[count].destroy
 else
  @report.participants[count] = Participant.find_or_create_by_email(@report.participants[count].email)
 end
 count += 1
end


@report.save!

任何帮助表示赞赏!
......这是我在这里的第一篇文章,希望没关系。

2 个答案:

答案 0 :(得分:0)

将对象分配给has_and_belongs_to_many关联时,该对象会自动保存

答案 1 :(得分:0)

关于你对count和num_of_participants的使用,我有点困惑。无论如何,我就是这样做的:

在更新视图中,您应该有一个声明为此的表单,对吗?

# views/reports/edit.html.erb
<%= form_for @report, :url => report_path(@report) do |f| -%>

如果您这样做,那么您用来输入电子邮件的文本字段应如下所示:

# views/reports/edit.html.erb
<%= f.text_field :emails, :name => "emails[]" %>

如果您使用form_tag代替form_for,则应使用text_field_tag代替f.text_field

为什么这样,你问?好吧,因为这样,你的所有电子邮件都会被params[:emails]包裹起来。它们都将在一个阵列中,这使得事情变得更加容易。

现在,我们要做的第一件事是获取与报告关联的当前电子邮件,并将它们与我们从表单中获得的电子邮件进行比较。如果其中一封电子邮件已从表单中删除,我们应将其从报告中删除。

# controllers/reports_controller.rb
@report.participants.each do |participant|
  if !params[:emails].include?(participant.email)
    @report.participants.delete(participant)  #remove the link to the participant from the report
  end
end

现在,我们需要遍历我们的电子邮件数组,如果报告没有该用户的电子邮件,请添加该参与者。

# controllers/reports_controller.rb
params[:emails].each do |email|
  participant = @report.participants.find_by_email(email)
  if participant.nil?
    @report.participants << Participant.find_or_create_by_email(email)
  end
end

就是这样!

@report.save!