I'm a designer/HTML+CSS dev learning Rails, and I'm having trouble with multiple user roles. My main models are as follows:
Studio
has_many :locations, dependent: :destroy
has_many :events, through: :locations
has_many :teachers, through: :events
Location
belongs_to :studio, :class_name => Studio, :foreign_key => "studio_id"
has_many :events
has_many :teachers, through: :events
Event
belongs_to :location, :class_name => Location, :foreign_key => "location_id"
belongs_to :studio
has_many :teachers
Teacher
belongs_to :event, :class_name => Event, :foreign_key => "event_id"
belongs_to :location
belongs_to :studio
has_one :user, :as => :roleable
accepts_nested_attributes_for :user
User
belongs_to :roleable, :polymorphic => true
The Teacher/User relationship is the tricky bit; I'm not sure if it should be reversed.
Users have basic profile info, Teachers have many details. All users can follow teachers, but teachers can also invite new teachers, and list other teachers as influences. I had this set up as
Teacher
has_many :guests, class_name: "Teacher", foreign_key: "host_id"
belongs_to :host, class_name: "Teacher"
has_many :influences, class_name: "Teacher", foreign_key: "student_id"
belongs_to :student, class_name: "Teacher"
User
has_many :favorites, class_name: "User", foreign_key: "fan_id"
belongs_to :fan, class_name: "User"
Does this look right, or should I say that User has_one :teacher ? The latter seems more correct, but it made my views really difficult. Thanks in advance!
Related
I have 2 models Event and User and two models for :through associations - event_member and event_organizer. I create few assocaitions, and in regular use it works, but in rails admin on Events and Event Organizer page I have an error:
ActiveRecord::AssociationNotFoundError in RailsAdmin
Association named 'event' was not found on EventOrganizer
When I change associations I start to get other RailsAdmin errors
schema.rb:
#event_members
t.bigint "member_id"
t.bigint "event_id"
#event_organizers
t.bigint "organizer_id"
t.bigint "organized_event_id"
In models I have next code:
Event
has_many :event_members
has_many :members, through: :event_members, source: :user
has_many :event_organizers
has_many :organizer, through: :event_organizers, source: :user
User
has_many :event_members, foreign_key: :member_id
has_many :events, through: :event_members
has_many :event_organizers, foreign_key: :organizer_id
has_many :events, through: :event_organizers, source: :user
EventOrganizer
belongs_to :user, foreign_key: :organizer_id
belongs_to :event, foreign_key: :organized_event_id
EventMember
belongs_to :user, foreign_key: :member_id
belongs_to :event
You have two definitions of has_many :events in User, and should change their names to make them unique and meaningful.
It was dummy problem with wrong scope, it was:
has_many :ogranized_event, through: :event_organizers, source: :event
Must be:
has_many :event_organized, through: :event_organizers, source: :organized_event
I have 3 tables:
User class
User has_many :project_assignments
User has_many :projects, through: :project_assignments
ProjectAssignment class
ProjectAssignment belongs_to :user
ProjectAssignment belongs_to :project_owner, class_name: 'User', foreign_key: 'user_creator_id'
ProjectAssignment belongs_to :project
Project
has_many :project_assignments
has_many :users, through: :project_assignments
ProjectAssignment has the columns:
project_id, user_id, creator_user_id
I want to get all the projects, for a user through creator_user_id
ex: current_user.created_projects
The query: ProjectAssignment.where(creator_user_id: current_user.id)
Can it be done when defining the relations in the models, the same as I did with projects but the foreign_key should be creator_user_id
I think you just need another couple of associations in User which leverage the creator_user_id field (as opposed to user.projects which will return the projects the user is a member of)
Try this -
#in User class
has_many :owned_project_assignments, :class_name => "ProjectAssignment", :as => :project_owner, :foreign_key => "user_creator_id"
has_many :owned_projects, :through => owned_project_assignments, :class_name => "Project", :source => :project, :as => :project_owner
the :source and :as options can be a bit tricksy, so this might not work, it's just off the top of my head...
In my case this was the correct solution:
has_many :owned_project_assignments, class_name: "ProjectAssignment", foreign_key: 'user_creator_id'
has_many :owned_projects, through: :owned_project_assignments, source: :project
I'm working on a Rails 4 app with complex associations and i cant figure out how to join one model to a parent.
Basically my apps logic is as follows
User
- belongs_to :account, polymorphic: true
Developer
- has_one :user, as: :account
- has_and_belongs_to_many :organizations
Organization
- has_one :user, as: :account
- has_and_belongs_to_many :developers
I decided to go this route over a STI because this allowed me to make my apps migration file cleaner and more organized
So there can be a Developer by itself and there can also be and Organization which holds many Developers, so i added has_and_belongs_to_many :organizations and has_and_belongs_to_many :developers to create this relationship. So everything works here in my app if i look up User.find().account.developers or User.find().account.organizations i get the associated records.
Now we get to the part where i am having trouble. Within my Rails app i have a model called App. A Developer can create many Apps by itself or a Developer can create and Organization and create many Apps within that Organization that all of the Developers who belong to that Organization have access too. I have no idea how to implement a relationship like this. Any suggestions?
Developer
has_one :user, as: :account
has_many :apps, as: :appable
has_and_belongs_to_many :founding_organizations, class_name: 'Organization', foreign_key: :founder_id
has_and_belongs_to_many :collaborating_organizations, class_name: 'Organization', foreign_key: :collaborator_id
has_and_belongs_to_many :organizations (Should this stay?)
Organization
has_one :user, as: :account
has_many :apps, as: :appable
has_and_belongs_to_many :founders, class_name: 'Developer', association_foreign_key: :founder_id
has_and_belongs_to_many :collaborators, class_name: 'Developer', association_foreign_key: :collaborator_id
has_and_belongs_to_many :developers (Should this stay?)
App
belongs_to :appable, polymorphic: true
/app/models/app.rb
App < ActiveRecord::Base
belongs_to :appable, :polymorphic => true
end
/app/models/organization.rb
Organization < ActiveRecord::Base
has_and_belongs_to_many :founders, :class_name => 'Developer', :association_foreign_key => :founder_id, :join_table => 'founders_organizations'
has_and_belongs_to_many :collaborators, :class_name => 'Developer', :association_foreign_key => :collaborator_id, :join_table => 'collaborators_organizations'
has_many :apps, :as => :appable
# Other relationships
end
/app/models/developer.rb
Developer < ActiveRecord::Base
has_and_belongs_to_many :founded_organizations, :class_name => 'Organization', :foreign_key => :founder_id, :join_table => 'founders_organizations'
has_and_belongs_to_many :collaborated_organizations, :class_name => 'Organization', :foreign_key => :collaborator_id, :join_table => 'collaborators_organizations'
has_many :apps, :as => :appable
# Other relationships
end
If you want a HABTM association. you need a join table. In Rails 4, you can add a migration file containing this:
create_join_table :developers, :organizations
Then just use:
Developer.find().organizations
or
Organization.find().developers
If you use User.find().account. you must get account's class first, then decide to use developers or organizations
I have a Collaboration model with a polymorphic association with a Grade | School, and a one-to-many association with a User
belongs_to :owner, polymorphic: true
belongs_to :user, foreign_key: "teacher_id"
this is the way i manage the users who can access a school or a grade. Now, what i need is to do something like this
School.first.teachers
Grade.first.teachers
I think it would be something like this in the Grade/School model
has_many :teachers, through: :collaborations, foreign_key: "teacher_id"
but it doesn't seem to be the right solution. Any ideas?
has_many :collaborations, :as => :owner
has_many :teachers, :through => :collaborations, :source => :user
You need to establish the polymorphic association to collaborations. Try:
class School < ActiveRecord::Base
has_many :collaborations, :as => :owner
has_many :teachers, :through => :collaborations
end
Trying to get to total number of users for a given event and I'm thinking what I've got should work, but I get the following:
Could not find the source association(s) :squads_users in model Squad. Try 'has_many :users, :through => :squads, :source => '. Is it one of :team, :event, :event_division, :users, :point_adjustments, :checkpoint_squads, :division, or :checkpoints?
My ActiveRecord Kung Fu is weak :-/
Event
has_many :squads
has_many :users, :through => :squads
Team
has_many :squads
Squad
belongs_to :event
belongs_to :team
has_and_belongs_to_many :users
SquadsUsers
belongs_to :user
belongs_to :squad
User
has_and_belongs_to_many :squads
Is your join model really named SquadsUsers? That might be the problem. It should be SquadUser.
Also, I think you want a many-to-many relationship between Event and Team, not Event and Squad, correct? In which case you need this:
Event
has_many :event_teams
has_many :teams, :through => :event_teams
EventTeam
belongs_to :event
belongs_to :team
Team
has_many :squads
Squad
belongs_to :team
has_many :squad_users
has_many :users, :through => :squad_users
SquadUser
belongs_to :squad
belongs_to :user
User
has_many :squads
You should remove your SquadsUsers model and just have a table called squads_users. has_and_belongs_to_many will automatically use this table without needing the additional model.