Пропустить проверку для некоторых элементов в связанных моделях во время создания / обновления - PullRequest
0 голосов
/ 07 декабря 2011

У меня есть следующие 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.Затем мне пришлось обновить update_attributes для контакта и адреса, а затем

@hotel.save :validate => false

, чтобы гарантировать, что исходные данные формы были сохранены полностью, как и ожидалось.

Это, без сомнения, очень плохая частькод.Может кто-нибудь сказать мне, как это убрать?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2012
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 во время создания.

0 голосов
/ 09 февраля 2012

Вы можете использовать фильтр, а именно 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).

Обновление : я перечитал ваш вопрос после ответа и обнаружил, что более запутался.Я предполагаю, что вы хотите создать форму, в которой пользователь не должен сразу же вводить банковский счет, но позже отредактировать его на другой странице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...