我有以下4个型号
Hotel (name)
has_one :address
has_one :contact
has_one :bank_account
validates_presence_of :name
def build_dependencies
build_contact
build_address
build_bank_account
end
Address (phone, street_address, hotel_id)
belongs_to :hotel
validates_presence_of :phone, :street_address
Contact (name, email, hotel_id)
belongs_to :hotel
validates_presence_of :name, :email
BankAccount (name, number, hotel_id)
belongs_to :hotel
validates_presence_of :name, :number
在用于创建酒店的表单中,我为联系人模型输入了名称和电子邮件的输入,但只接收了地址模型的电话。
HotelController#new
@hotel = Hotel.new
@hotel.build_dependencies #this creates empty Contact and Address to generate the form fields
#render the form to create the hotel
HotelController#create
#receive form data
@hotel = Hotel.new
@hotel.build_dependencies
@hotel.save :validate => false
@hotel.attributes = params[:hotel]
@hotel.save :validate => false
这是我能够创建酒店的唯一方式,其中包含联系信息,来自地址的电话和空银行账户。我不得不打电话给
@hotel.save :validate => false
第一次使用BankAccount,Address,Contact的空白实例保存Hotel实例。然后我必须在联系人和地址上更新update_attributes然后
@hotel.save :validate => false
确保原始表单数据按预期完全保存。
毫无疑问,这是一段非常糟糕的代码。谁能告诉我如何清理它?
答案 0 :(得分:0)
您可以使用过滤器,即after_create
来调用关联的模型,以在保存@hotel
变量后创建关联的记录。
我碰巧遇到了同样的问题,这是我的解决方案。对不起,经过这么长时间这可能没有用,但对未来的用户来说这将是件好事。
class User < ActiveRecord::Base
has_one :bank_account
# Filter -- After Creation
after_create :create_default_bank_account
def create_default_bank_account
self.build_bank_account
self.bank_account.save(:validate=>false)
# :validate=>false must be called on the bank_account's save. I made the mistake of trying to save the user. =(
end
这样,您可以从create
操作中创建空行,IMHO应该属于模型。然后,您可以使用edit
操作让用户“创建”银行帐户条目。使用此功能,您只需要标准的创建操作(例如,由rails g scaffold_controller
生成)。
更新:我在回答之后重新阅读了您的问题,发现自己更加困惑。我假设您要呈现一个表单,其中不希望用户立即进入银行帐户,而是稍后在另一页面上进行编辑。
答案 1 :(得分:0)
Address
validates_presence_of :phone, :on => :create, :if => proc { |u| u.creating_hotel? }
validates_presence_of :street, :phone, :on => :update
Contact
validates_presence_of :name, :email :on => :update
def creating_hotel?
addressable_type == 'Hotel'
end
用户只有在创建酒店后才能看到:street, :name, :email
字段,并且在创建过程中会看到:phone
。