Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Many to One association

Hi I am new to rails and started with a simple app which has many 'tasks' and each one have a 'tag' attached with it. So the relationship is like - Many 'tasks' have one/same 'tag'. How do I bring this up in my models. I tried it with 'task' has_one 'tag' and a 'tag' belongs_to a 'task' rule but it works only for the first 'task' with that tag and for the rest of the 'tasks' with the same 'tag' it won't work. Please suggest me the way to do this properly. Thanks :)

class Task < ActiveRecord::Base
  has_many :logs
  has_one :tag , :foreign_key => "id"
end

class Tag < ActiveRecord::Base
  belongs_to :task
end
like image 751
sarath Avatar asked Jan 02 '12 03:01

sarath


2 Answers

It looks to me like you have the associations turned around - every newbie to Rails that I've ever seen has done this on their first project.

What you want is

class Task < ActiveRecord::Base
  has_many :logs
  belongs_to :tag
end

class Tag < ActiveRecord::Base
  has_many :tasks
end

Think about it this way - if you click on a tag, you would expect a list of all tasks that have that tag. So tags have many tasks, and each task belongs to one tag. This matches how you described your project. Has_one is intended for a one to one relationship, where each task would have its own, unique tag.

like image 65
kimhagen Avatar answered Oct 10 '22 13:10

kimhagen


Your issue is possibly that using the foreign key "id" means that you're using the Tags table "ids" column as your key, which is illogical. In this case, a Task of id 1 thinks it will be associated to a Tag of id 1.

If you set your migrations up using the RAILs conventions, I would assume you have a column in the tags table that records the task_id.. In this case I think you would just need these associations:

 class Task < ActiveRecord::Base
   has_many :logs
   has_one :tag
 end

 class Tag < ActiveRecord::Base
   belongs_to :task
 end

Again, this would assume you have an attribute for tags called "task_id". If you saved it in an unconventional key eg "custom_name_task_id" it would change to

 class Task < ActiveRecord::Base
   has_many :logs
   has_one :tag, :foreign_key => "custom_name_task_id"
 end

 class Tag < ActiveRecord::Base
   belongs_to :task
 end
like image 26
jay Avatar answered Oct 10 '22 13:10

jay