Проверка уникальности вложенных данных. Использование драгоценного камня кокона

В настоящее время у меня есть модель клиента с ценами has_many.

Таблица цен:

create_table "pricings", force: true do |t|
    t.integer  "product_id"
    t.integer  "client_id"
    t.decimal  "unit_price"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

Модель ценообразования:

class Pricing < ActiveRecord::Base
  belongs_to :client
  belongs_to :product  
  validates :unit_price, presence: true  
end

Модель клиента:

class Client < ActiveRecord::Base
  has_many :deliveries
  has_many :collections
  has_many :pricings
  accepts_nested_attributes_for :pricings, allow_destroy: true

  scope :order_by_name, -> { order('lower(name)') }

  validates :name, :address, :vat_number, presence: true 
  validates :pricings,  presence:  { :message => ": Products must be added for a client before you can save." }
end

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

Я использую гем кокона («кокон», «~> 1.2.3» — https://github.com/nathanvda/cocoon) и нашел эту статью, чтобы помочь мне, но я действительно изо всех сил пытаюсь понять, куда я должен добавить код?

Ссылка на код, который я не понимаю: http://techbrownbags.wordpress.com/2014/02/05/rails-validation-of-cocoon-nested-forms/

Как я могу адаптировать этот код к моей ситуации?


person Mulaiko    schedule 08.04.2014    source источник
comment
edgeguides.rubyonrails.org/   -  person BroiSatse    schedule 09.04.2014
comment
@BroiSatse по какой-то причине не работает для вложенных форм.   -  person Mulaiko    schedule 09.04.2014
comment
Вы используете кокон?   -  person BroiSatse    schedule 09.04.2014
comment
ааа да кокон (и не канкан - я отредактировал свой вопрос). когда я добавляю этот код, проверяется: цены, уникальность: { область действия: : product_id, сообщение: нельзя добавлять один и тот же продукт более одного раза. } я получаю эту ошибку - NoMethodError в ClientsController#create undefined method `attributes' for #‹ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Pricing:0x859cd30›   -  person Mulaiko    schedule 09.04.2014
comment
Вам нужно добавить это в модель Pricing - я опубликую ответ.   -  person BroiSatse    schedule 09.04.2014


Ответы (1)


Вам нужно добавить проверку в вашу модель ценообразования:

class Pricing < AR::Base

  validates :product_id, uniqueness: true

end

Обратите внимание, что даже при этом есть вероятность того, что в вашу базу данных будут введены два дубликата (особенно, когда вы используете многопоточный сервер, такой как unicorn, или ваше приложение работает на нескольких серверах). Чтобы быть на 100% уверенным, вы должны ввести ограничение db. Вы можете сделать это с помощью простой миграции:

add_index :pricings, :product_id, :unique => true  
person BroiSatse    schedule 09.04.2014