How to query nested associations in rails - ruby-on-rails

My models are
campaign.rb
has_many: views_logs
user.rb
has_many :views_logs
views_log.rb
belongs_to :campaign
belongs_to :user
I want to get Campaign.first.views_logs.uniq.users.genders
I know this query this is wrong but basically I want to get this

You need to define the direct relationship with the through parameter:
class ModelName
has_many :views_logs
has_many :users through: :views_logs
end
Then you can query it like this: model_name.user.where(gender: 'male')

Related

Specifying Conditions on Multiple Nested Eager Loaded Associations

I'm trying to query on ActiveRecord multiple nested eager loaded associations with conditions like so:
user.books.includes(slot: [room: :school]).where("books.slot.room.school.id = 1")
Obviously this query is wrong, but basically what I'm trying to reach is a relation of user.books for a certain school.
My model structure is:
class User < ActiveRecord::Base
has_many :books
has_many :slots, through: :books
has_many :rooms, through: :slots
has_many :schools
end
class Book < ActiveRecord::Base
belongs_to :user
belongs_to :slot
end
class Slot < ActiveRecord::Base
has_many :books
belongs_to :room
end
class Room < ActiveRecord::Base
belongs_to :school
has_many :slots
end
class School < ActiveRecord::Base
has_many :users
has_many :rooms
has_many :slots, through: :rooms
has_many :books, through: :slots
end
Any ideas? Thanks in advance.
includes eager loads association records, while joins does what you want to do.
This question has been asked here numerous times. Please make sure that you look and try to find a similar question here before you ask one.
So you want to change your code like this:
user.books.joins(slot: [room: :school]).where(schools: { id: 1 })

Can the joins table created by a has_many :through relation also have a has_many relation?

The model created by the has_many through relation would look like this:
class MerchantOrder < ActiveRecord::Base
belongs_to :order
belongs_to :user
has_many :products
end
But I am not sure if this is possible. Any reason why this wouldn't work?

Rails: stringing together multiple has_many relationships

I have three models which look something like this:
Class User < ActiveRecord::Base
has_many :comments
end
Class Comment < ActiveRecord::Base
belongs_to :user
has_many :votes
end
Class Vote < ActiveRecord::Base
belongs_to :comment
end
Now I want to get all the votes associated with a user's comments like so:
#user.comments.votes
But this throws the error:
undefined method `votes' for #<ActiveRecord::Relation:0x3f6f8a0>
This seems like it should work, but I suspect ActiveRecord is coughing on the deeper has_many relationship. I've hacked together an SQL query that gets the desired results, but I suspect there's a cleaner way using purely ActiveRecord. Any tips?
You should use a has_many :through association
In your case it would be
Class User < ActiveRecord::Base
has_many :comments
has_many :votes, :through => :comments
end
Class Comment < ActiveRecord::Base
belongs_to :user
has_many :votes
end
Class Vote < ActiveRecord::Base
belongs_to :comment
end
And then simply get the votes with
#user.votes
Try this:
Vote.joins(comment: :user).where(users: {id: #user.id})

Nested models with has_many in Rails

For example I have in my app model User, that has_many models Post. And Post has_many Attachment. So I can do this
user.posts
and this
post.attachment
But what if I want do smth like
user.attachments
Is there any build-in solution for this?
You would use a has_many through association. You should end up with something similar to the following structure:
class User < ActiveRecord::Base
has_many :posts
has_many :attachments, :through => :posts
end
class Post < ActiveRecord::Base
has_many :attachments
end
class Attachments < ActiveRecord::Base
belongs_to :posts
end
The relevant section from the above link:
The has_many :through association is also useful for setting up “shortcuts” through nested has_many associations...

ActiveRecord::HasManyThroughAssociationNotFoundError in UserController#welcome

I have a many to many relationship in rails. All database tables are named accordingly and appropriately. All model files are plural and use underscore to seperate words. All naming comventions are followed by ruby and rails standards. I'm using has many through in my models like this:
has_many :users, :through => :users_posts #Post model
has_many :posts, :through => :users_posts #User model
belongs_to :users #UsersSource model
belongs_to :posts #UsersSource model
What else could this error be from?
ActiveRecord::HasManyThroughAssociationNotFoundError in UsersController#welcome
Could not find the association :users_posts in model Post
You need to define the join model as a separate association when using has_many :through:
class Post < ActiveRecord::Base
has_many :user_posts
has_many :users, :through => :user_posts
end
class User < ActiveRecord::Base
has_many :user_posts
has_many :posts, :through => :user_posts
end
class UserPost < ActiveRecord::Base
belongs_to :user # foreign_key is user_id
belongs_to :post # foreign_key is post_id
end
This works best when you need to keep data that pertains to the join model itself, or if you want to perform validations on the join separate from the other two models.
If you just want a simple join table, it's easier to use the old HABTM syntax:
class User < ActiveRecord::Base
has_and_belongs_to_many :posts
end
class Post < ActiveRecord::Base
has_and_belongs_to_many :users
end

Resources