Сохранение принадлежащих данных при создании новой записи - PullRequest
1 голос
/ 12 декабря 2011
class Party < ActiveRecord::Base
  belongs_to :hostess, class_name: 'Person', foreign_key: 'hostess_id'
  validates_presence_of :hostess
end

class Person < ActiveRecord::Base
    has_many :parties, foreign_key: :hostess_id
end

При создании нового Party представление позволяет пользователю выбрать существующий Hostess или ввести новый.(Это делается с помощью автозаполнения jQuery для поиска существующих записей.) Если выбрана существующая запись, params[:party][:hostess_id] будет иметь правильное значение.В противном случае params[:party][:hostess_id] - это 0, а params[:party][:hostess] содержит данные для создания нового Hostess (например, params[:party][:hostess][:first_name] и т. Д.)

В контроллере Parties:

def create
  if params[:party][:hostess_id] == 0
    # create new hostess record
    if @hostess = Person.create!(params[:party][:hostess])
      params[:party][:hostess_id] = @hostess.id
    end
  end
  @party = Party.new(params[:party])
  if @party.save
    redirect_to @party, :notice => "Successfully created party."
  else
    @hostess = @party.build_hostess(params[:party][:hostess])
    render :action => 'new'
  end
end

Это нормально работает, когда я передаю существующий Hostess, но не работает при попытке создать новый Hostess (не удается создать новый Hostess/Person и, следовательно, не удается создать новый Party).Есть предложения?

1 Ответ

4 голосов
/ 12 декабря 2011

Учитывая предоставленные вами модели, вы можете получить эту настройку более чистым способом, используя несколько инструментов рельсов, таких как inverse_of, accepts_nested_attributes_for, attr_accessor и обратные вызовы.

# Model
class Party < ActiveRecord::Base
  belongs_to :hostess, class_name: 'Person', foreign_key: 'hostess_id', inverse_of: :parties
  validates_presence_of :hostess

  # Use f.fields_for :hostess in your form
  accepts_nested_attributes_for :hostess

  attr_accessor :hostess_id

  before_validation :set_selected_hostess

  private
  def set_selected_hostess
    if hostess_id && hostess_id != '0'
      self.hostess = Hostess.find(hostess_id)
    end
  end
end

# Controller
def create
  @party = Party.new(params[:party])

  if @party.save
    redirect_to @party, :notice => "Successfully created party."
  else
    render :action => 'new'
  end
end  

Мы 'здесь делают довольно много вещей.

Прежде всего, мы используем inverse_of в ассоциации belongs_to, что позволяет проверять наличие родительской модели .

Во-вторых, мыВы используете accepts_nested_attributes_for, который позволяет вам передать params[:party][:hostess] в модель вечеринки и позволить ей построить хозяйку для вас.

В-третьих, мы настраиваем attr_accessorдля :hostess_id, который немного очищает логику контроллера, позволяя модели решать, что делать, получает ли он hostess объект или значение hostess_id.

В-четвертых, мы уверены, чтопереопределить hostess существующей хозяйкой, если мы получили правильное значение hostess_id.Мы делаем это, назначая хозяйку в обратном вызове before_validation.

На самом деле я не проверял, работает ли этот код, но, надеюсь, он предоставит достаточно информации для решения вашей проблемы и предоставит более полезную информацию.инструменты, скрывающиеся в рельсах.

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