0

This has been a nightmare for me and I'm willing to give an arm and an eyeball to the person who can help me :P I'm going to explain this as best as possible.

When a user edits their 'profile' they can type in skills that they have in nested attributes fields (they can click 'Add Another Skill' and it will populate another field for them to type). When they begin to type, jquery-autocomplete kicks in. They MUST select an item from autocomplete. When they save, for example, 3 skills, we get this:

table: skills

+-----------+----------------+
|  user_id  |     skill      |
+-----------+----------------+
|     4     |  Photoshop     |
+-----------+----------------+
|     4     |  Illustrator   |
+-----------+----------------+
|     4     |  InDesign      |
+-----------+----------------+

Now, what I want to do is NOT store the actual skill names. Instead, I want to store the ID of the skill from skills_vocabulary list (which is what the jquery-autocomplete uses).

table: skills_vocabulary

+------+----------------+
|  id  |     skill      |
+------+----------------+
|  1   |  Illustrator   |
+------+----------------+
|  2   |  Dreamweaver   |
+------+----------------+
|  3   |  After Effects |
+------+----------------+
|  4   |  InDesign      |
+------+----------------+
|  5   |  Photoshop     |
+------+----------------+
|  6   |  Flash         |
+------+----------------+

THUS, the skills table should look like this:

+-----------+----------------+
|  user_id  |    skill_id    |
+-----------+----------------+
|     4     |        5       |
+-----------+----------------+
|     4     |        1       |
+-----------+----------------+
|     4     |        4       |
+-----------+----------------+

Any help would be greatly, greatly, greatly appreciated. I've been at war with this for an embarrassing 3 months.

Thank you all.

EDIT/

<%= f.fields_for :skills do |builder| %>
    <%= render "skills_fields", :f => builder %>
  <% end %>
  <p><%= link_to_add_fields "Add a Skill", f, :skills %></p>     

_skills_fields.html.erb

<div class="fields ac skills">
    <div class="clearfix">
        <span class="left"><%=f.autocomplete_field :name, users_autocomplete_skills_vocab_name_path, :class => 'restricted_to_autocomplete' %></span><span class="remove_link left"><%= link_to_remove_fields "[x]", f %></span>
    </div>
</div>

EDIT 2/

Right now it's just

skill.rb

class Skill < ActiveRecord::Base
  belongs_to :user
end

user.rb

class User < ActiveRecord::Base
  has_many :tskills, :dependent => :destroy
  accepts_nested_attributes_for :tskills, :allow_destroy => true, :reject_if => lambda { |a| a[:name].blank? }
end

skills_vocabulary.rb

class SkillsVocabulary < ActiveRecord::Base

end

My controller code is the basic index, show, new, create, update, destroy

The list of skills (about 10,000 items long) is in the table skills_vocabularies

stewart715
  • 5,557
  • 11
  • 47
  • 80
  • 1
    I would recommend you use http://loopj.com/jquery-tokeninput/. There is also a railscast for it: http://railscasts.com/episodes/258-token-fields. If not, take a look at code of https://github.com/crowdint/rails3-jquery-autocomplete and get started to change stuff around. – rubish Jul 27 '11 at 14:07
  • You can also take a look at SO question(http://stackoverflow.com/questions/6727183) to also add skills, while auto-completing them. This is sleeker than user clicking again and again to add a new skill – rubish Jul 27 '11 at 14:10
  • @Rubish I am actually currently using rails3-jquery-autocomplete -- We might decide to let them add things that aren't in autocomplete and have it autoadd to the database. It's just the referencing to the vocab table that is troubling me. – stewart715 Jul 27 '11 at 14:13
  • I meant take a look at code of gem and customize things to your needs. I would recommend jquery-tokeninput AGAIN. The SO question, defines the basic idea of adding things while one types. Have recently migrated from jquery-ui-autocomplete to tokeninput and I am loving it :) – rubish Jul 27 '11 at 14:22

1 Answers1

3

This should be your classes:

class User < ActiveRecord::Base
  has_and_belongs_to_many :skills
end

class Skill < ActiveRecord::Base
  has_and_belongs_to_many :users
end

and this is the migration which creates them

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :name
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

class CreateSkills < ActiveRecord::Migration
  def self.up
    create_table :skills do |t|
      t.string :name
      t.timestamps
    end
  end

  def self.down
    drop_table :skills
  end
end

class SkillsUsers < ActiveRecord::Migration
  def self.up
    create_table :skills_users, :id => false do |t|
      t.integer :skill_id
      t.integer :user_id
    end
  end

  def self.down
    drop_table :skills_users
  end
end

then add a new skill is as simple as

user.skills << Skill.find(1) # to add a skill
user.skills = Skill.all      # to add many of them

Look here fo further details

Update: I ve tried the autocomplete gem and I think you should accept the Rubish Gupta suggestion, i.e. use my models plus jquery token input because it will handle pretty well many-to-many associations. Autocomplete gem as far as I saw is for 1-to-n associations.

Moreover you have a full working example in rails to play with.

Fabio
  • 18,856
  • 9
  • 82
  • 114
  • Thanks, not sure this will work for what I have set up though. I've edited my question with my form fields. Will these work? – stewart715 Jul 27 '11 at 14:52
  • I don't know the rails3-jquery-autocomplete gem, so I can't answer directly to your question. BTW I think my example will fit your needs, because it's only related to the server part. So you should update your question with controller and model code. – Fabio Jul 27 '11 at 14:59
  • Edited, again...thanks so much for taking the time. The jquery gem just autocompletes the text field -- where it saves is the same as any other normal text field. – stewart715 Jul 27 '11 at 15:05
  • I mean, I can use the text form just fine..it's just the speed takes a huge hit querying text vs numbers.. – stewart715 Jul 27 '11 at 15:30
  • I keep getting `Unknown key(s): dependent` – stewart715 Jul 27 '11 at 15:46
  • If you want to keep the associations between user and skills as id pairs you MUST change your model relationships and insert the `has_and_belongs_to_many` or `has_many, :through`, and adapt your autocomplete code to this change. – Fabio Jul 27 '11 at 18:04