Here's the setup:
class Project < ActiveRecord::Base
has_many :project_subject_areas, class_name: "Project::SubjectArea"
has_many :subject_areas, through: :project_subject_areas
end
class SubjectArea < ActiveRecord::Base
has_many :project_subject_areas, class_name: "Project::SubjectArea"
has_many :projects, through: :project_subject_areas
end
class Project::SubjectArea < ActiveRecord::Base
belongs_to :project
belongs_to :subject_area, class_name: '::SubjectArea'
end
Running this in Rails:
[ SubjectArea.to_s, Project::SubjectArea.to_s ].inspect
gives:
["SubjectArea", "SubjectArea"]
but running this (after server restart):
[ Project::SubjectArea.to_s, SubjectArea.to_s ].inspect
gives:
["Project::SubjectArea", "SubjectArea"]
file structure is:
models/project.rb
models/subject_area.rb
models/project/subject_area.rb
I can bypass this with require project/subject_area manually, but am I doing something wrong with this namespacing?
Is there any other way to namespace my models?
When Rails generates namespaces rails generate Project::X I get Project as a module, but I need it to be an ActiveRecord class. I also have some other models that belong to Project and I really want them to be namespaced and in models/project/ directory.
Related
I have the following Rails models connecting teams and users:
class User < ActiveRecord::Base
has_many :memberships
has_many :teams, through: :memberships
end
class Team < ActiveRecord::Base
has_many :memberships
has_many :users
end
class Membership < ActiveRecord::Base
belongs_to :team
belongs_to :user
end
I want to implement a team manager via the existing memberships table.
Would it be a better idea to have a foreign key in the teams table like this:
class Team < ActiveRecord::Base
belongs_to :manager_membership, class_name: 'Membership'
has_one :manager, through: :manager_membership, source: :user
# ...
end
Or would it be better to have an extra column (with unique index) on memberships like this:
class Team < ActiveRecord::Base
has_one :manager_membership, -> where { manager: true }, class_name: 'Membership'
has_one :manager, through: :manager_membership, source: :user
# ...
end
I wonder if having foreign keys going both ways from team to a membership and back is weird? Or maybe it doesn't make much difference either way?
Based on the comments, you should be able to use a single table inheritance for both your users and managers. That would mean you get to use the same membership relationship on both models.
class User < ActiveRecord::Base
has_many :memberships
has_many :teams, through: :memberships
end
class Manager < User
# your code
end
You can now use Manager wherever needed, and add any validations directly on that model. Remember to add a type column to your User table if you decide to go this route.
EDIT
Looking at this again, you will need to have a separate table to keep the relationship between your Manager's team and the actual team they manage clear. Yourteam` should be something like:
class Team < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
has_many :teams_managers
has_many :managers, through: :teams_managers
end
class Manager < User
has_many :teams_managers
# note here we're aliasing for clarity and specifying a source
has_many :managed_teams, through: :teams_managers, source: :team
end
# this is your association model for managers <-> teams
class TeamsManager < ActiveRecord::Base
belongs_to :manager
belongs_to :team
end
# so now you could call something like this
manager = Manager.find 1
manager.managed_teams =>[...]
manager.teams =>[...]
You'd have to make the corresponding migrations to instantiate your TeamsManagers table as well.
I can't seem to work around the name convention or if I'm joining them incorrectly.
This is the error I'm getting from the user model:
> user.companies
NameError: uninitialized constant User::CompaniesUser
And from the company model:
> company.users
NameError: uninitialized constant Company::CompaniesUser
user.rb
has_many :companies_users
has_many :companies, :through => :companies_users
company.rb
has_many :companies_users
has_many :users, :through => :companies_users
company_user.rb
class CompanyUser < ActiveRecord::Base
belongs_to :company
belongs_to :user
end
I've been looking up through examples but I honestly don't understand why it keeps exploding. If there's any additional information needed, I'll provide it, I appreciate any help given.
Your association companies_users will be mapped to class named CompaniesUser by Rails because "companies_users".classify will give you CompaniesUser. But the class you want to associate is CompanyUser, so the solution in this case would be to modify your associations to include class_name option as follows:
# user.rb
has_many :companies_users, class_name: CompanyUser
has_many :companies, :through => :companies_users
# company.rb
has_many :companies_users, class_name: CompanyUser
has_many :users, :through => :companies_users
Update: This is of course if you want to stick with the association name companies_users, otherwise #Babur has a solution for you.
It should be:
has_many :company_users
has_many :companies, :through => :company_users
Only last word should be pluralized
Because of your has_many :companies_users in your Company model, Rails tried to load a model class for that table, that be convention would be called CompaniesUser. To make your code work, you could either change your has_many declaration to
has_many :company_users
or even get rid of the CompanyUser model completely and use has_and_belongs_to_many instead.
class User
has_and_belongs_to_many :companies
end
class Company
has_and_belongs_to_many :users
end
I'm working on an API in Rails and have hit a wall. I'm missing something stupid I imagine, but I can't see it.
https://gist.github.com/3989396
I can not get associations passed in the item.json to create an association. I thought that Rails would hook these up.
The relations for the accounts need to be fixed like so:
item.rb:
belongs_to :expense_account, class_name: "Account"
belongs_to :income_account, class_name: "Account"
account.rb:
has_many :items, inverse_of: :expense_account
has_many :items, inverse_of: :income_account
I have a model named Container. This model just has a list of associated Links. So I created tables containers, links and containers_links. Now I want to connect my two models. So I did
class Container < ActiveRecord::Base
has_many :links, :through => :containers_links
end
class Links < ActiveRecord::Base
has_many :containers, :through => :containers_links
end
But I have an error because I don't have reflection with containers_links in my model. I can add something like
has_many :containers_links
But I don't have a model ContainersLinks (and I don't want to create one). What should I do?
You can use has_and_belongs_to_many relationship
class Container < ActiveRecord::Base
has_and_belongs_to_many :links
end
class Links < ActiveRecord::Base
has_and_belongs_to_many :containers
end
But you still need to create join table.
In a Rails 3.2 app I need to set up two associations between the same two models.
For example
class User
has_many :events
has_many :attendances
has_many :attended_events, through: :attendances
end
class Event
belongs_to :event_organizer, class_name: "User"
has_many :attendances
has_many :attendees, through: :attendances, class_name: "User"
end
class Attendance
belongs_to :attended_event, class_name: "Event"
belongs_to :attendee, class_name: "User"
end
This is the first time I've experimented with aliasing class names, and I'm having trouble getting it to work. I'm not sure if the issue lies with how I've defined the associations, or elsewhere.
Do my associations look OK? Have I overlooked something needed to get this to work?
The problem I'm having is that no user ids are being set in the Attendance model. This may be a stupid question, but given my associations above, should the field name be :user_id or :event_organizer_id?
Really appreciate any suggestions on this. Thanks!
foreign_key to be specified in User and Event
class User
has_many :events
has_many :attendances, foreign_key: :attendee_id
has_many :attended_events, through: :attendances
end
class Event
belongs_to :event_organizer, class_name: "User"
# here it should be event_organizer_id
has_many :attendances, foreign_key: :attended_event_id
has_many :attendees, through: :attendances
end
class Attendance
belongs_to :attended_event, class_name: "Event"
# this should have attended_event_id
belongs_to :attendee, class_name: "User"
# this should have attendee_id because of 1st param to belongs_to here is "attendee"
# and same should be added as foreign_key in User model
# same follows for Event too
end