Я фактически создаю систему таксономии в своем приложении. Вот моя таблица схема:Лучшая практика Rails для использования полиморфной ассоциации
Taxonomies
class CreateTaxonomies < ActiveRecord::Migration
def change
create_table :taxonomies do |t|
t.references :taxonomable, polymorphic: true
t.integer :term_id
end
end
end
Условие
class CreateTerms < ActiveRecord::Migration
def change
create_table :terms do |t|
t.string :name
t.string :type
t.integer :parent_id, default: 0
end
end
end
и вот мои ассоциации:
class Taxonomy < ActiveRecord::Base
belongs_to :taxonomable, polymorphic: true
end
class Term < ActiveRecord::Base
self.inheritance_column = :_type_disabled // because I use type as table field
has_many :taxonomies, as: :taxonomable
end
Чтобы сделать его более универсальным, я вызывают беспокойство:
module Taxonomable
extend ActiveSupport::Concern
included do
has_many :taxonomies, as: :taxonomable
end
def get_associate_terms
terms = self.taxonomies.map { |t| t.term_id }
taxonomies = Term.find terms
end
end
и я в том числе это в моей модели:
class Post < ActiveRecord::Base
include Taxonomable
end
Он отлично работает, и я могу извлечь связанные данные с помощью get_associate_terms
. Моя проблема находится внутри моего контроллера и моей формы. Я на самом деле сохранить его так:
# posts/_form.html.haml
= f.select :taxonomy_ids, @categories.map { |c| [c.name, c.id] }, {}, class: 'form-control'
# PostsController
def create
@post = current_user.posts.new(post_params)
if @post.save
@post.taxonomies.create(term_id: params[:post][:taxonomy_ids])
redirect_to posts_path
else
render :new
end
end
Этот метод создания правильно сохранения данных, но если вы посмотрите на атрибут PARAMS, вы увидите, что объект taxonomies
ждет term_id
, но я могу используйте только taxonomy_ids
в моей форме. Это кажется грязным, и я хотел, чтобы ваша точка зрения не позволяла так взломать.
Кроме того, я думаю, что эта проблема связана с приведенной выше, при редактировании моего элемента в поле выбора не проверяется, что фактическая соответствующая категория ассоциируется с текущим сообщением.
Любые мысли приветствуются.
Большое спасибо
EDIT:
Вот моя форма
= form_for @post, url: posts_path, html: { multipart: true } do |f|
= f.select :taxonomy_ids, @categories.map { |c| [c.name, c.id] }, {}, class: 'form-control'
EDIT 2:
Я добавил accepts_nested_attributes_for
в мое беспокойство как это:
module Taxonomable
include do
has_many :taxonomies, as: :taxonomable, dependent: :destroy
accepts_nested_attributes_for :taxonomies
end
end
, а затем использованный fields_for
в моей форме:
= f.fields_for :taxonomies_attributes do |taxo|
= taxo.label :term_id, 'Categories'
= taxo.select :term_id, @categories.map { |c| [c.name, c.id] }, {}, class: 'form-control'
При отправке формы, я получаю это:
"post"=>{"type"=>"blog", "taxonomies_attributes"=>{"term_id"=>"2"}, "reference"=>"TGKHLKJ-567TYGJGK", "name"=>"My super post"
Однако, когда сообщение было сохранено с успехом, ассоциации не являются. Есть идеи???
EDIT 3:
В мой контроллер, я добавил это:
def post_params
params.require(:post).permit(
taxonomies_attributes: [:term_id]
)
end
При отправке формы, я получил следующее сообщение об ошибке:
no implicit conversion of Symbol into Integer
Согласно этому сообщению Rails 4 nested form - no implicit conversion of Symbol into Integer, это потому, что я использую taxonomies_attributes
в своих fields_for
как:
= f.fields_for :taxonomies_attributes do |taxo|
Однако, если удалить его:
= f.fields_for :taxonomies do |taxo|
Блок не отображает ничего, кроме DIV оберточной его:
<div class="form-group">
<!-- Should be display here but nothing -->
</div>
EDIT 4:
Наконец сделать это работает. Тот факт, что окно выбора не показывалось, объясняется тем, что при создании нового ресурса мой @post
не имеет таксономий. Делая следующие исправления, что:
def new
@product = current_user.products.new
category = @product.taxonomies.build
end
спасибо всем
Что вы хотите сказать? – tyler
Извините, если я не понял. Я хотел бы знать, есть ли лучший способ сохранить эту полиморфную ассоциацию? Спасибо – lkartono