Rails4 reject_if и проверка не работают: невозможно сохранить без вложенных объектов

#validation #activerecord #ruby-on-rails-4 #nested-attributes

#проверка #activerecord #ruby-on-rails-4 #вложенные атрибуты

Вопрос:

У меня есть эти две модели

 class Transaction < ActiveRecord::Base
  has_many :order, :inverse_of => :transaction, :dependent => :destroy
  accepts_nested_attributes_for :order, :allow_destroy=> true, :reject_if=> :menu_id_validation
  def menu_id_validation(attributes)
    attributes['menu_id'].blank?
  end
end

class Order < ActiveRecord::Base
  belongs_to :transaction, :inverse_of => :order
  belongs_to :menu
  validates :menu_id, :presence => true
  validates_presence_of :transaction
end
  

Когда я отправляю подобные параметры для создания транзакции:

 Parameters: {"utf8"=>"✓", "authenticity_token"=>"...",
"transaction"=>{..., "customer_id"=>"30", "staff_id"=>"8", 
"order_attributes"=>{"0"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"1"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"2"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"},
"3"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}}},
"commit"=>"save”}
  

Я ожидаю, что :reject_if отбросит все параметры заказа, потому что ни у одного из них нет ‘menu_id’ и фактически:menu_id_validation возвращает для них значение true .
Однако я не смог сохранить это и получил ошибку проверки модели заказа :menu.

Очень странная вещь, я могу сохранить это, заполнив хотя бы один из параметров заказа, чтобы иметь:menu_id. И если я сохраню объект модели транзакции с некоторым объектом модели заказа, я могу удалить их все следующим образом.

 Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", 
"transaction"=>{...,"customer_id"=>"10", "staff_id"=>"8",
"order_attributes"=>{"0"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"true", "id"=>"219"}, 
"1"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"2"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}, 
"3"=>{"menu_id"=>"", "price"=>"", "num"=>"1", "_destroy"=>"false"}},},
"commit"=>"save", "id"=>"108"}
  

Первые параметры уже сохранены в БД и будут уничтожены с помощью «_destroy» => true . При этом все объекты модели вложенного порядка удаляются.Но это можно сохранить.

Я думаю, что эта проблема вызвана конфликтом (?) между проверкой порядка и :reject_if . Что я должен сделать, чтобы сохранить объект модели транзакции, даже если он еще не сохранен и не имеет объекта модели заказа?

Ответ №1:

Я думаю :reject_if , что будет использоваться только имя метода в связанной модели (в данном случае Order ), например, :new_record? или proc, который воздействует на хэш вложенного атрибута, например proc {|attrs| attrs['menu_id'].blank? } . Таким образом, вы либо захотите использовать proc (хорошая идея, поскольку ваше условие выглядит как только одна строка), либо определить :menu_id_validation внутри вашей Order модели, а не внутри Transaction .

Комментарии:

1. Достаточно ли это ответило на ваш вопрос? Помогло ли это? Если это так, было бы неплохо, если бы вы приняли мой ответ.