Rails:在保存更新之前操纵参数 - 错误的方法?

时间:2010-07-13 16:26:40

标签: ruby-on-rails

首先,我觉得我接近这个错误的方式,但我不知道怎么做。这也有点难以解释,所以请耐心等待。

我使用Javascript来允许用户在编辑表单中添加多个文本区域,但这些文本区域用于单独的模型。它基本上允许用户以两种模式而不是一种模式编辑信息。以下是关系:

class Incident < ActiveRecord::Base
  has_many   :incident_notes
  belongs_to :user
end

class IncidentNote < ActiveRecord::Base
  belongs_to :incident
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :incidents
  has_many :incident_notes
end

当用户添加“事件记录”时,它应自动识别该特定用户的记事。我还希望多个用户能够为同一事件添加备注。

我遇到的问题是,当用户添加新的文本区域时,rails无法确定新的incident_note属于用户。因此它最终创建了incident_note,但user_id为零。例如,在日志中,当我编辑表单并添加新注释时,我会看到以下插入语句:

INSERT INTO "incident_notes" ("created_at", "updated_at", "user_id", "note", "incident_id") VALUES('2010-07-02 14:09:11', '2010-07-02 14:09:11', NULL, 'Another note', 8)

所以我决定尝试做的是操作params:更新方法中的事件。这样我就可以自己添加user_id了,不过这看起来像铁轨一样,但我不知道怎么回事。

提交表单时,参数如下所示:

Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"at/FBNxjq16Vrk8/iIscWn2IIdY1jtivzEQzSOn0I4k=", "id"=>"18", "customer_id"=>"4", "controller"=>"incidents", "incident"=>{"title"=>"agggh", "incident_status_id"=>"1", "incident_notes_attributes"=>{"1279033253229"=>{"_destroy"=>"", "note"=>"test"}, "0"=>{"id"=>"31", "_destroy"=>"", "note"=>"asdf"}}, "user_id"=>"2", "capc_id"=>"SDF01-071310-004"}}

所以我想我可以编辑这一部分:

"incident_notes_attributes"=>{"1279033253229"=>{"_destroy"=>"", "note"=>"test"}, "0"=>{"id"=>"31", "_destroy"=>"", "note"=>"another test"}}

正如您所看到的,其中一个还没有id,这意味着它将被新插入到表中。

我想为新项添加另一个属性,因此它看起来像这样:

"incident_notes_attributes"=>{"1279033253229"=>{"_destroy"=>"", "note"=>"test", "user_id" => "2"}, "0"=>{"id"=>"31", "_destroy"=>"", "note"=>"another test"}}

但是这看起来似乎没有轨道,我不知道如何绕过它。以下是事件控制器的更新方法。

# PUT /incidents/1
# PUT /incidents/1.xml
def update
  @incident = @customer.incidents.find(params[:id])

  respond_to do |format|
    if @incident.update_attributes(params[:incident])
    # etc, etc
end 

我想我可能会添加如下内容:

params[:incident].incident_note_attributes.each do |inote_atts|
  for att in inote_atts
    if att.id == nil
      att.user_id = current_user.id
    end
  end
end

但显然incident_note_attributes不是一种方法。所以我不知道该怎么做。我该如何解决这个问题?

对不起文字墙。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:3)

我有类似的要求,这就是我解决它的方法:

class Incident < ActiveRecord::Base
  has_many   :incident_notes
  belongs_to :user

  attr_accessor :new_incident_note

  before_save :append_incident_note

  protected

  def append_incident_note
    self.incident_notes.build(:note => self.new_incident_note) if !self.new_incident_note.blank?
  end
end

然后在表单中,您只需使用标准导轨form_for并使用new_incident_note作为属性。

我选择了这种方法,因为我知道它只是将数据投入到带有少量数据验证的笔记中。如果您有深入验证,那么我建议您使用accepts_nested_attributes_forfields_for。这是有充分记录的here