Учитывая предоставленные вами модели, вы можете получить эту настройку более чистым способом, используя несколько инструментов рельсов, таких как 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
.
На самом деле я не проверял, работает ли этот код, но, надеюсь, он предоставит достаточно информации для решения вашей проблемы и предоставит более полезную информацию.инструменты, скрывающиеся в рельсах.