Reputation: 974
I tried to set up a basic association between users and projects:
user.rb
class User < ActiveRecord::Base
has_many :projects, foreign_key: 'owner_id'
has_many :project_members, through: :project_members
end
project.rb
class Project < ActiveRecord::Base
has_many :project_members, dependent: :destroy
has_many :users, through: :project_members
end
project_member.rb
class ProjectMember < ActiveRecord::Base
belongs_to :user
belongs_to :project
end
my project_members table:
+----+------------+---------+
| id | project_id | user_id |
+----+------------+---------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
+----+------------+---------+
and my project table:
+----+-------+----------+
| id | name | owner_id |
+----+-------+----------+
| 1 | test1 | 1 |
| 2 | test2 | 2 |
+----+-------+----------+
why I get with
current_user.projects
only the projects where the projects.owner_id = current_user.id and not the projects where the user is member?
But I think it's the wrong side I tried to get the data I want. I'm on /projects where the projects controller gets the data. I think I should use something like that:
class ProjectsController < ApplicationController
# GET /projects
def index
@projects = Project.all
end
end
but how I can get only the projects where current_user.id is member of?
Upvotes: 2
Views: 999
Reputation: 76774
As an addition to Kasper Johansen
's answer, you may also wish to look into has_and_belongs_to_many
:
The main reason you'd use this is because you're not using any extra attributes in your join model (which is your current setup).
If you want to keep it that way, you can do away with your join model by using the has_and_belongs_to_many
association in place of has_many :through
:
#app/models/user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :projects
end
#join table - projects_users
#app/models/project.rb
class Project < ActiveRecord::Base
has_and_belongs_to_many :users
end
From the docs:
The simplest rule of thumb is that you should set up a
has_many :through
relationship if you need to work with the relationship model as an independent entity. If you don't need to do anything with the relationship model, it may be simpler to set up ahas_and_belongs_to_many
relationship (though you'll need to remember to create the joining table in the database).
In regards your original problem, you have to also remember that in order to get the data back from an associative model, you have to set up the associations that will be populated with that data.
You mention...
why I get with
current_user.projects
only the projects where theprojects.owner_id = current_user.id
... because you've set the association of has_many :projects, foreign_key: 'owner_id'
Rails is not magic - it has to take what associations you give it and populate the data in those methods accordingly:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :owned_projects, class_name: "Project", foreign_key: :owner_id
has_and_belongs_to_many :projects
end
#app/models/project.rb
class Project < ActiveRecord::Base
has_and_belongs_to_many :users
end
Hopefully gives you some more context to add to Kasper
's answer.
Upvotes: 3
Reputation: 1253
I think you should set that up a tiny bit different:
class User < ActiveRecord::Base
has_many :owned_projects, class_name: "Project", foreign_key: 'owner_id', dependent: :restrict_with_error
has_many :project_members, dependent: :destroy
has_many :projects, through: :project_members
end
class Project < ActiveRecord::Base
has_many :project_members, dependent: :destroy
has_many :users, through: :project_members
belongs_to :owner, class_name: "User"
end
In order to get all the projects the current_user is a member of you can do:
current_user.projects
In order to get all the projects the current_user owns you can do:
current_user.owned_projects
Upvotes: 5