Rails 3: Как принудительно завершить проверку модели при сбое проверки связанной модели? - PullRequest
1 голос
/ 18 декабря 2010

У меня есть следующие две модели:

class Product < ActiveRecord::Base
  belongs_to :shop      
  validates_numericality_of :price, :greater_than_or_equal_to => 0
end

class Shop < ActiveRecord::Base
  has_many :products
  validates_presence_of :name
end

Вот метод create моего ProductsController:

def create
  if params[:product][:shop_id] == "new_shop"
    @shop = Shop.find_by_name(params[:new_shop]) || Shop.create(:name => params[:new_shop]) # Is there a simpler method to do this ?
    params[:product][:shop_id] = @shop.id
  end

  @product = Product.new(params[:product])

  if @product.save
    redirect_to(:action => 'index')
  else
    render('new')
  end 
end

Когда пользователь добавляет новый продукт, он имеетустановите флажок, чтобы выбрать магазин.Последняя опция в этом поле выбора позволяет пользователю добавить новый магазин (появляется дополнительное текстовое поле ввода).value этой последней опции - new_shop.

Если проверка нового введенного магазина завершится неудачно, я бы хотел, чтобы проверка продукта завершилась неудачно и отобразилась соответствующая ошибка (в настоящее время отображается только ошибка).если проверка самого продукта не удалась).

Каким будет самый «метод Rails 3» для достижения этого?

Ответы [ 2 ]

4 голосов
/ 18 декабря 2010

Я думаю, было бы проще, если вы используете accepts_nested_attributes_for.Итак, к вашей Product модели добавьте:

accepts_nested_attributes_for :shop

И затем в зависимости от значения списка выбора вы можете изменить форму (в js), так что будет либо поле shop_id, либо целый наборполей для магазина:

<% f.fields_for :shop do |sf| %>
  ...
<% end %>

Тогда, если пользователь выбирает существующий магазин, он пропустит только shop_id, но если пользователь выберет новый магазин, то форма также пропустит и новый связанный объект.Если вы хотите, чтобы название магазина было уникальным, просто добавьте validates_uniqueness_of к Shop модели.

Если проверка магазина не удалась, продукт не будет сохранен.По сути, ваш контроллер остается настолько простым, насколько это возможно (просто создавая новый объект продукта из params - вам нет дела до магазина там).

2 голосов
/ 18 декабря 2010

Я согласен с @klew, вы, вероятно, должны использовать accepts_nested_attributes_for.

Но простой и прямой ответ на ваш вопрос заключается в использовании validates_associated.

Кроме того, лучший способ сделать:

@shop = Shop.find_by_name(params[:new_shop]) || Shop.create(:name => params[:new_shop])

будет:

@shop = Shop.find_or_create_by_name(params[:new_shop])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...