I'm actually creating a taxonomy system into my application. Here is my tables schema :
Taxonomies
class CreateTaxonomies < ActiveRecord::Migration
def change
create_table :taxonomies do |t|
t.references :taxonomable, polymorphic: true
t.integer :term_id
end
end
end
Terms
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
and here are my associations :
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
To make it more generic, I create a concern :
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
and I'm including it into my model :
class Post < ActiveRecord::Base
include Taxonomable
end
It works fine and I can retreive the associated data using get_associate_terms
. My problem is located within my controller and my form. I'm actually saving it like that :
# 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
This create method is saving the data correctly but if you take a look at the params attribute, you will see that the object taxonomies
is waiting for a term_id
but I can only use taxonomy_ids
in my form. It feels kind of dirty and I wanted to have your point of view to avoid hacking around like that.
Also, and I think this problem is linked with the one above, when editing my item, the select box is not checked the actual matching category associate to the current post.
Any thoughts are welcome.
Thanks a lot
EDIT :
Here is my form
= 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 :
I added the accepts_nested_attributes_for
to my concern as it :
module Taxonomable
include do
has_many :taxonomies, as: :taxonomable, dependent: :destroy
accepts_nested_attributes_for :taxonomies
end
end
and then used fields_for
in my form :
= 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'
When submitting the form, I receive it :
"post"=>{"type"=>"blog", "taxonomies_attributes"=>{"term_id"=>"2"}, "reference"=>"TGKHLKJ-567TYGJGK", "name"=>"My super post"
However, when the post has been saved with success, the associations are not. Any ideas???
EDIT 3 :
In my controller, I added this :
def post_params
params.require(:post).permit(
taxonomies_attributes: [:term_id]
)
end
When submitting the form, I've got the following error :
no implicit conversion of Symbol into Integer
According to that post Rails 4 nested form - no implicit conversion of Symbol into Integer, it's because I'm using taxonomies_attributes
in my fields_for
as:
= f.fields_for :taxonomies_attributes do |taxo|
However, if I remove it to :
= f.fields_for :taxonomies do |taxo|
The block is displaying nothing except the div wrapping it :
<div class="form-group">
<!-- Should be display here but nothing -->
</div>
EDIT 4 :
Finally make it works. The fact that the select box was not showing came from the fact that when creating a new resource, my @post
has no taxonomies. Doing the following fix that :
def new
@product = current_user.products.new
category = @product.taxonomies.build
end
thanks to everyone