0

我有以下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 实例。然后我必须更新联系人和地址的属性,然后

@hotel.save :validate => false

以确保原始表单数据按预期完全保存。

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

4

2 回答 2

0

You can use a filter, namely the after_create to call the associated model to create associated records after saving of the @hotel variable.

I happen to be facing the same problem and here's my solution. Sorry this probably is not helpful after such a long while but it'll be good for future users.

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

This way, you can take the empty row creation out of the create action, which IMHO, should belong to the Model. You can then use the edit action to let users "create" the bank account entry. Using this, you only need a standard create action (e.g. generated by rails g scaffold_controller).

Update: I re-read your question after answering and found myself to be more confused. I assume you want to render a form where the user is not expected to enter the bank account immediately but edit it later on another page.

于 2012-02-09T12:42:45.170 回答
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

于 2012-02-11T02:31:03.030 回答