开发者

Rails: Manipulating params before saving an update - wrong approach?

开发者 https://www.devze.com 2023-01-07 16:28 出处:网络
First, I feel like I am approaching this the wrong way, but I\'m not sure how else to do it.It\'s somewhat difficult to explain as well, so please bear with me.

First, I feel like I am approaching this the wrong way, but I'm not sure how else to do it. It's somewhat difficult to explain as well, so please bear with me.

I am using Javascript to allow users to add multiple text areas in the edit form, but these text areas are for a separate开发者_运维百科 model. It basically allows the user to edit the information in two models rather than one. Here are the relationships:

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

When the user adds an "incident note", it should automatically identify the note with that particular user. I also want multiple users to be able to add notes to the same incident.

The problem I ran into is that when a user adds a new text area, rails isn't able to figure out that the new incident_note belongs_to the user. So it ends up creating the incident_note, but the user_id is nil. For example, in the logs I see the following insert statement when I edit the form and add a new note:

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)

So what I've decided to try to do is manipulate the params for :incident in the update method. This way I can just add the user_id myself, however this seems un-rails-like, but I'm not sure how else to it.

When the form is submitted, the parameters look like this:

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"}}

So I thought I could edit this section:

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

As you can see, one of them does not have an id yet, which means it will be newly inserted into the table.

I want to add another attribute to the new item so it looks like this:

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

But again this seems un-rails-like and I'm not sure how to get around it. Here is the update method for the Incident controller.

# 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 

I thought I might be able to add something like the following:

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

But obviously incident_note_attributes is not a method. So I'm not sure what to do. How can I solve this problem?

Sorry for the wall of text. Any help is much appreciated!


I have a similar requirement and this is how I tackled it:

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

and then in the form, you just use a standard rails form_for and use the new_incident_note as the attribute.

I chose this method because I knew it was just throwing data into the notes with minor data validations. If you have in depth validations, then I recommend using accepts_nested_attributes_for and fields_for. That is very well documented here.

0

精彩评论

暂无评论...
验证码 换一张
取 消