2012-01-12 6 views
0

У меня есть то, что я полагаю, должна быть общая ситуация, но, возможно, не может найти способ выражения вопрос, чтобы получить решение ...Самый простой способ редактирования ассоциации в Rails

У меня есть несколько связанных модели в моей заявке:

class Product < ActiveRecord::Base 
    validates_uniqueness_of :prod_code 
end 

class Stock < ActiveRecord::Base 
    belongs_to :product 
end 

Фактически, существует ряд других моделей, которые также относятся к Продукту. По умолчанию в записи запаса я вижу поле product_id, которое является автоматически увеличивающимся числом, которое не очень помогает пользователю. Продукты имеют уникальный prod_code, который находится на штрих-кодах и т. Д., И является естественным ключом базы данных продукта.

Что бы я хотел, для создания/редактирования экранов для акций и других связанных моделей, чтобы показать текстовое поле для prod_code и иметь возможность реагировать на параметры в форме stock[prod_code] разумным способом (например, смотреть (например, Stock.new(params[:stock]))

Чтобы уточнить, установочный ресурс [prod_code] ничего не изменит в базе данных продукта, вместо этого он заменит product_id для соответствующая запись запаса, то есть привязка записи запаса к другой записи продукта.

В настоящее время у меня есть различные методы, определенные в s tock, например prod_code=, которые делают эту работу. Но, как я уже упоминал, на самом деле есть несколько моделей, которые относятся к моей таблице продуктов. Есть ли способ определить что-то внутри модели продукта?

например. что-то вроде метода referenced_by, который расскажет всем связанным моделям об аргументе prod_code, просмотрев его в таблице продуктов?

class Product < ActiveRecord::Base 
    validates_uniqueness_of :prod_code 
    referenced_by :prod_code 
end 
+0

Я не уверен, что вы делаете с вложенным кодом продукта; он представлен в виде текстового поля - означает ли это, что он введен вручную? Во всяком случае, accepts_nested_attributes, я думаю, это то, что вы ищете, хотя я думаю, что вам нужно будет установить отношения has_one из Stock to Product http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html – mark

+0

Мне кажется, что вложенные атрибуты, например, редактирование базы данных кода продукта с экранов акций. Это не то, что я хочу сделать - я просто хочу разрешить пользователю вводить новый код продукта на экране редактирования акций. – asc99c

+0

Идея состояла бы в том, чтобы я мог зайти в вид на леса и, например, в _form.html.erb, измените: product_id на: prod_code, и все будет работать. На экране редактирования будет отображаться текущий код продукта, пользователь может ввести новый. – asc99c

ответ

2

Возможно, вы захотите использовать вложенные формы.

Сначала вы можете сказать модель принимать вложенные атрибуты (api for nested attributes), как

accepts_nested_attributes_for :product 

в вашем складе модели.

Тогда в вашей форме вы можете использовать поля_файлы (api for fields_for), чтобы вложить поля продукта в свою складскую форму. Представьте себе что-то вроде:

= form_for(@stock) do |form| 
    = form.text_field :some_stock_attribute 
    = form.fields_for(@stock.product) do |product_form| 
    = product_form.text_field :prod_code 

Это существенно гнездится имя вашего prod_code поля формы, чтобы «запас [product_attributes] [prod_code]», в то время как, благодаря accepts_nested_attributes_for, ваш запас модель готова передать product_attributes к соответствующему продукту.

Update (см комментарии):

Способ referenced_by, как вы понимаете, не существует. Также вам придется немного позаботиться, а затем просто изменить связанный с ним продукт. Вы все равно хотите отобразить ошибку, если prod_code не существует, я предполагаю.

Грубо вы можете добавить виртуальный атрибут к акциям, что позволяет вашей складской форме иметь текстовое поле: prod_code (add attr: prod_code to stock model).

Во-вторых, перед проверкой вам, вероятно, понадобится метод, который ищет продукт для prod_code и изменяет связь или добавляет ошибку: prod_code.

это может выглядеть укус так:

class Stock 
    attr :prod_code 

    before_validation :associate_product_from_prod_code 

    def associate_product_from_prod_code 
    unless self.product = Product.where(:prod_code => prod_code) 
     errors[:prod_code] << "Product Code is not valid" 
    end 
    end 

end 
+0

Спасибо за ответ, но это не совсем то, что я ищу. Что бы это сделало, так это изменить файл prod_code в записи продукта. То, что я пытаюсь сделать, это использовать prod_code для изменения product_id, с которым связана запись запаса. Я исправлю этот вопрос, потому что думаю, что его нельзя объяснить слишком хорошо! – asc99c

+0

Но вы не хотите использовать поле выбора для product_id, но вместо этого есть текстовое поле для ввода пользователем prod_code/ – trueunlessfalse

+0

в порядке, вы уже ответили на это. – trueunlessfalse

0

Вы можете использовать prod_code вместо product_id как foreign_key:

class Stock 
    belongs_to :product, :foreign_key => "prod_code" 
end 

Или вы можете установить его на продукт:

class Product 
    has_many :stocks, :foreign_key => "prod_code" 
    has_many :images, :foreign_key => "prod_code" 
    has_many :sizes, :foreign_key => "prod_code" 
end 
Смежные вопросы