Validation 在创建/更新期间跳过关联模型中某些成员的验证

Validation 在创建/更新期间跳过关联模型中某些成员的验证,validation,ruby-on-rails-3.1,model-associations,Validation,Ruby On Rails 3.1,Model Associations,我有以下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) b

我有以下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.save :validate => false
确保原始表单数据按预期完全保存


毫无疑问,这是一段非常糟糕的代码。有人能告诉我如何清理吗?

在保存
@hotel
变量后,您可以使用过滤器,即
after\u create
调用关联模型来创建关联记录

我碰巧也面临同样的问题,下面是我的解决方案。很抱歉,这可能在这么长时间后没有帮助,但对未来的用户有好处

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
class用户false)
#:validate=>false必须在银行账户的save上调用。我犯了一个错误,试图拯救用户=(
终止
这样,您可以从IMHO应该属于模型的
create
操作中创建空行。然后,您可以使用
edit
操作让用户“创建”银行帐户条目。使用此操作,您只需要一个标准的创建操作(例如,由
rails g scaffold\u controller
生成)

更新:回答后,我重新阅读了您的问题,发现自己更加困惑。我假设您希望呈现一个表单,其中用户不需要立即输入银行帐户,而是稍后在另一页上编辑它

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