How to apply tags with acts_as_taggable_on using c

2019-02-01 02:54发布

问题:

I would like to assign two different "types" of tags (sector categories and free tagging) to a Company model using acts_as_taggable_on. NB: I'm new to RoR!

This is easy to do if just using standard text input fields, but I would like to use check-boxes on one type (a fixed sector category tag that is predefined), and then allow the user to add comma separated tags in an input field.

I have played around with this problem in various ways,... one inspired by this question...but I cannot get it to work

Here is what I have so far:

# models/company.rb
class Company ...
  acts_as_taggable_on :tags, :sectors

  has_many :taggings,
           :as => :taggable,
           :include => :tag,
           :class_name => "ActsAsTaggableOn::Tagging",
           :conditions => { :taggable_type => "Company" }

  has_many :sector_tags, 
           :through => :taggings, 
           :source => :tag,
           :class_name => "ActsAsTaggableOn::Tag",
           :conditions => {:context => "sectors"}
end

in the form (using simple_form gem) I have...

# views/companies/_form.html.haml
= simple_form_for @company do |f|
  = f.input :name
  = f.association :sector_tags, :as => :check_boxes, :hint => "Please click all that apply"
  = f.input :tag_list
  = f.button :submit, "Add company"

And in my Company controller I have

# controllers/companies_controller.rb
def create
  @company = current_user.companies.build(params[:company])
  if @company.save
  ...
end

But this causes a validation error:

ActiveRecord::RecordInvalid in CompaniesController#create
Validation failed: Context can't be blank

Can anyone hint at how I can do this right?

A related question is if this is a good way to do it at all? Would I be better off just using a Category model for assigning sector tags through a joint model?

Thanks!

回答1:

Well, I solved my problem. And it turned out to be quite simple. Alas, I ended up creating a separate Sector model through a joint "sectorizations" table. But if anyone is interested, I just wanted to update on what I did in the case above...

In my company model

# models/company.rb
class Company ...
  acts_as_taggable_on :tags, :sectors
...
end

in the form

# views/companies/_form.html.haml
= simple_form_for @company do |f|
  = f.input :name
  = f.input :sector_list, :as => :check_boxes, :collection => @sectors, :hint => "Please check all that apply"
  = f.input :tag_list
  = f.button :submit, "Add company"

and in the company controller (create)

# controllers/company_controllers.rb
def new
  @company = Company.new
  @sectors = get_sectors
end

def get_sectors
  sectors = []
  for sector in Company.sector_counts
    sectors << sector['name']
  end
  return sectors
end


回答2:

It seems that act_as_taggable_on uses single table inheritance, so you actually don't need to create any additional tables. However you do need to follow their convention (that they never stated) as follows:

//add to model
attr_accessible :yourfieldname_list
acts_as_taggable_on :yourfieldname

//view
<%= f.text_field :yourfieldname_list %>