I have the following models:
class User < ActiveRecord::Base
has_many :groups, :through => :memberships
has_many :memberships, :class_name => "User::Group"
end
class Group < ActiveRecord::Base
has_many :users, :through => :members
has_many :members, :class_name => "User::Group"
end
class User::Group < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
I make the following association call:
#user.groups
And it returns an array of User::Groups, instead. Am I overlooking something?
I changed the name of the join table to User::Membership, and now everything works as expected. It seems that naming the last part of the namespace after another model was causing some sort of interference, though I'm not sure why. Does anyone have a more informed explanation?
Related
This may be tough for me to explain, so if it's not clear just let me know so I can edit as needed!
I have the following example:
class User < ActiveRecord::Base
has_many :topics
has_many :memberships
end
class Topic < ActiveRecord::Base
belongs_to :user
end
#join model between User and Group
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :members, :through => :memberships, :source => :user
has_many :topics, :through => :members
end
The problem I'm having is that I am trying to create a feed (#feed_topics) of all topics that are owned by all the members of the groups I am a member of, and I'm driving myself a little nuts.
Should I try to make this happen using associations, or make an instance method in my User model that has some ActiveRecord/SQL to union all the groups' members' topics into one ActiveRecord::Relation object?
My goal is to write current_user.feed_topics in my controller's action.
Sorry for not explaining earlier! The idea was to utilize 'Nested has_many_through's in order to get to your feed topics. This concept is documented here under the heading 'Nested Associations': http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html.
Let me know if this still is unclear (or if it doesn't work).
class User < ActiveRecord::Base
has_many :topics
has_many :memberships
has_many :groups, :through => :membership
has_many :group_members, :through => :groups, :source => :member
has_many :feed_topics, :through => :group_members, :source => :topic
end
So far these are the final versions of the models from the original question (topic and membership did not change):
class User < ActiveRecord::Base
has_many :topics
has_many :memberships
has_many :groups, :through => :memberships
has_many :feed_topics, :through => :groups, :source => :member_topics
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :members, :through => :memberships, :source => :user
has_many :member_topics, :through => :members, :source => :topics
end
I am testing right now by adding more groups and members to see if it pulls in all the other members' topics of other groups.
EDIT: things seem to be working ok.
EDIT2: one little problem I had was seeing duplicate topics because a member was in multiple groups. I learned about :uniq => true and it saved the day.
I've started learning Rails recently and have completed the sample app at http://ruby.railstutorial.org. I am trying to add user-created groups to the sample social network. I've gotten stuck at how exactly I should model the group. I know there should be a user_id of who owns the group and there should be strings of the name and description. Aside from that I have no idea what the rest of the group data model should look like. Thank you in advance.
If you want a user to be in multiple groups your relations should be something like this
class Group < ActiveRecord::Base
belongs_to :owner, :class_name => "User"
has_many :memberships
has_many :members, :through => :memberships
end
class Membership < ActiveRecord::Base
belongs_to :member, :class_name => "User"
belongs_to :group
end
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, :through => :memberships
has_many :owned_groups, :class_name => "Group", :foreign_key => "owner_id"
end
What about something like this?
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
end
Caution: I am a 4 week old at programming. I am having trouble with a has_many :through => relationship between my Neighborhood and Cta_train models.
Here are my models:
class CtaTrain < ActiveRecord::Base
belongs_to :Ctaline
has_and_belongs_to_many :searches
has_many :neighborhoods, :through => :CtaLocation, :foreign_key => :neighborhood_id
has_many :CtaLocations
end
class Neighborhood < ActiveRecord::Base
has_many :geopoints
has_many :listings
has_many :properties
has_and_belongs_to_many :searches
has_many :CtaTrains, :through => :CtaLocation, :foreign_key => :cta_train_id
has_many :CtaLocations
end
class CtaLocation < ActiveRecord::Base
belongs_to :neighborhood
belongs_to :CtaTrain
end
When I try to do this:
neighborhood.CtaTrains
I get this error:
ActiveRecord::HasManyThroughAssociationNotFoundError (Could not find the association :CtaLocation in model Neighborhood):
I have been slogging through this for several hours now....I have tried many iterations of ideas from stackoverflow....what I show above feels like the closest solution, but obviously still not working. Any thoughts would be appreciated!
I think the problem is that you're not following Rails conventions by using lowercase/underscore for your symbols. Class names have to be CamelCase but you should be doing the following everywhere else:
class CtaTrain < ActiveRecord::Base
belongs_to :cta_line
has_and_belongs_to_many :searches
has_many :neighborhoods, :through => :cta_locations, :foreign_key => :neighborhood_id
has_many :cta_locations
end
*Update: You should also be using :cta_locations (plural) in your has many through
Imagine 4 models in Rails 3.1
class Student < ActiveRecord::Base
has_many :memberships
has_many :courses, :through => :memberships
has_many :tests, :through => :courses
end
class Membership < ActiveRecord::Base
belongs_to :student
belongs_to :course
end
class Course < ActiveRecod::Base
has_many :tests
has_many :students, :through => :memberships
end
class Test < ActiveRecord::Base
belongs_to :course
end
How can I output a sorted list (ie by date) of a student's upcoming tests
(I'm guessing there is a fairly simple answer, but I've been trying in vain for a while)
My best guess is something like:
#upcomingTests = #currstudent.tests.sort_by &:testDateTime
but it seems to return an empty array
First of all, there is an slight error on your model "Course". It needs "belongs_to :student".
class Course < ActiveRecod::Base
has_many :tests
has_many :students, :through => :memberships
belongs_to :student
end
After you've created and populated a foreign key, you can create a simple named_scope on your test mode:
named_scope :ordered, :order => "created_at DESC"
Then it's just the matter of accessing it from wherever you want:
#ordered_tests = #student.tests.ordered
Can't wrap my head around this...
class User < ActiveRecord::Base
has_many :fantasies, :through => :fantasizings
has_many :fantasizings, :dependent => :destroy
end
class Fantasy < ActiveRecord::Base
has_many :users, :through => :fantasizings
has_many :fantasizings, :dependent => :destroy
end
class Fantasizing < ActiveRecord::Base
belongs_to :user
belongs_to :fantasy
end
... which works fine for my primary relationship, in that a User can have many Fantasies, and that a Fantasy can belong to many Users.
However, I need to add another relationship for liking (as in, a User "likes" a Fantasy rather than "has" it... think of Facebook and how you can "like" a wall-post, even though it doesn't "belong" to you... in fact, the Facebook example is almost exactly what I'm aiming for).
I gathered that I should make another association, but I'm kinda confused as to how I might use it, or if this is even the right approach. I started by adding the following:
class Fantasy < ActiveRecord::Base
...
has_many :users, :through => :approvals
has_many :approvals, :dependent => :destroy
end
class User < ActiveRecord::Base
...
has_many :fantasies, :through => :approvals
has_many :approvals, :dependent => :destroy
end
class Approval < ActiveRecord::Base
belongs_to :user
belongs_to :fantasy
end
... but how do I create the association through Approval rather than through Fantasizing?
If someone could set me straight on this, I'd be much obliged!
Keep your first set of code, then in your User Model add:
has_many :approved_fantasies, :through => :fantasizings, :source => :fantasy, :conditions => "fantasizings.is_approved = 1"
In your Fantasizing table, add an is_approved boolean field.