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インスタンスを初めて保存します。それから私は連絡先と住所のupdate_attributesをしなければならなかったそしてそれから

@hotel.save :validate => false

元のフォームデータが期待どおりに完全に保存されたことを確認します。

これは間違いなく、非常に悪いコードです。誰かがこれをきれいにする方法を教えてもらえますか?

4

2 に答える 2

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 に答える
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

更新:私は答えた後にあなたの質問を読み直しました、そして私はもっと混乱していることに気づきました。ユーザーが銀行口座をすぐに入力することを期待されていないフォームをレンダリングしたいが、後で別のページで編集したいとします。

于 2012-02-09T12:42:45.170 に答える