Рельсы создают модель с несколькими own_to, с attr_accessible

Мои модели выглядят примерно так:

class User < ActiveRecord::Base
    attr_accessible: :name

    has_many :reviews   
end

class Product < ActiveRecord::Base
    attr_accessible: :name

    has_many :reviews   
end

class Review < ActiveRecord::Base
    attr_accessible: :comment

    belongs_to :user    
    belongs_to :product
    validates :user_id, :presence => true
    validates :product_id, :presence => true
end

Я пытаюсь выяснить, как лучше всего создать новый обзор, учитывая, что :user_id и :product_id недоступны для attr_accessible. Обычно я просто создаю обзор через ассоциацию ( @user.reviews.create ), чтобы автоматически установить :user_id, но в этом случае я не уверен, как также установить product_id.

Насколько я понимаю, если я сделаю @user.reviews.create(params), все параметры, не относящиеся к attr_accessible, будут проигнорированы.


person k_day    schedule 20.01.2012    source источник
comment
Чем больше я об этом думаю, тем больше кажется, что product_id должен быть attr_accessible в классе Review, поскольку пользователю нужно будет выбрать рецензируемый продукт из веб-формы.   -  person k_day    schedule 20.01.2012


Ответы (2)


Ты можешь сделать:

@user.reviews.create(params[:new_review])

...или похожие. Вы также можете использовать вложенные атрибуты:

class User < ActiveRecord::Base
  has_many :reviews
  accepts_nested_attributes_for :reviews
  ...

См. «Примеры вложенных атрибутов» на http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html.

person Paul Cantrell    schedule 20.01.2012
comment
Привет, Пол. Можете ли вы объяснить, откуда берется params[:new_review] в вашем первом предложении? - person k_day; 20.01.2012
comment
Из блока fields_for или просто набора закодированных вручную входных данных (например, text_field_tag ​​вместо f.text_field). Другими словами, сверните свои собственные поля обзора. Однако вам, вероятно, нужны вложенные атрибуты: fields_for + accepts_nested_attributes_for. - person Paul Cantrell; 21.01.2012

Похоже, вы хотели бы реализовать связь «многие ко многим» между моделями «Пользователь» и «Продукт», при этом модель «Обзор» служит в качестве таблицы соединения для соединения двух с добавленной строкой комментария. Этого можно добиться с помощью ассоциации has many through в Rails. Начните с прочтения руководств Rails по ассоциациям.

При настройке модели Review добавьте внешние ключи для User и Product:

rails generate model review user_id:integer product_id:integer

И настройте свои ассоциации следующим образом:

class User < ActiveRecord::Base
  has_many :reviews
  has_many :products, through: :reviews
end

class Product < ActiveRecord::Base
  has_many :reviews
  has_many :users, through: :reviews
end

class Review < ActiveRecord::Base
  # has comment string attribute
  belongs_to :user
  belongs_to :product
end

Это позволит вам совершать такие звонки, как:

user.products << Product.first
user.reviews.first.comment = 'My first comment!'

Вот как вы могли бы создать обзор:

@user = current_user
product = Product.find(params[:id])
@user.reviews.create(product: product)
person paniwani    schedule 20.01.2012
comment
На самом деле я не думаю, что мне нужны has_many :products, через: :reviews и has_many :users, через: :reviews биты, поскольку мне не нужны отношения «многие ко многим» между продуктами и пользователями. Мне просто нужно, чтобы пользователь мог оставить отзыв о продукте, поэтому каждый отзыв должен принадлежать пользователю и продукту. Вот немного синтаксиса в вашем ответе, которого я не понимаю: @user.reviews.create(product: product) Будет ли это по-прежнему заполнять product_id, даже если product_id не attr_accessible? - person k_day; 20.01.2012