Rails: манипулирование параметрами перед сохранением обновления - неправильный подход? - PullRequest
2 голосов
/ 13 июля 2010

Во-первых, я чувствую, что подхожу к этому неправильным путем, но я не уверен, как еще это сделать. Это тоже сложно объяснить, поэтому, пожалуйста, потерпите меня.

Я использую 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 не может понять, что новая запись инцидента принадлежит пользователю. Таким образом, в итоге создается инцидент, но 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)

Итак, я решил попробовать изменить параметры для: инцидента в методе обновления. Таким образом, я могу просто добавить 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"}}

Как видите, у одного из них еще нет идентификатора, что означает, что он будет вновь вставлен в таблицу.

Я хочу добавить еще один атрибут к новому элементу, чтобы он выглядел так:

"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 Ответ

3 голосов
/ 13 июля 2010

У меня есть похожее требование, и вот как я его выполнил:

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_for и fields_for.Это очень хорошо задокументировано здесь .

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