Rails ActiveRecord How to get array of associated models - ruby-on-rails

I am using Ruby on Rails 4.0.1 and I would like to get the array of associated models. That is, I have the following models and associations:
class Post < ActiveRecord::Base
has_many :comments, dependent: :destroy
has_many :likes, dependent: :destroy
end
class Comment < ActiveRecord::Base
belongs_to :post
end
class Like < ActiveRecord::Base
belongs_to :post
end
And I would like to get the array of associated models likes following.
Post.has_many_associated
=> [:comments, :likes]
Any Idea?
Thank you for your advice.
Tae-ho.

Yes, you can do this with reflect_on_all_associations:
Post.reflect_on_all_associations(:has_many).map(&:name)

Related

Arrange items in an array by the time they were added to that array?

Basically I have a Collection model and a Post model, where a Collection has many posts and a Post belongs to many collections. So I'll occasionally push posts to the #collection.posts array using <<, to replicate a post being added to a collection. Now is there a way to order the posts in #collection.posts by the time they were pushed to that array? If yes, how?
All relevant models:
user.rb
class User < ActiveRecord::Base
has_many :posts, dependent: :destroy
has_many :collections, dependent: :destroy
end
post.rb
class Post < ActiveRecord::Base
belongs_to :user
has_many :collectables
has_many :collections, through: :collectables
end
collection.rb
class Collection < ActiveRecord::Base
belongs_to :user
has_many :collectables
has_many :posts, through: :collectables
end
collectable.rb
class Collectable < ActiveRecord::Base
belongs_to :post
belongs_to :collection
end
I guess adding an order scope to the definition of the association would work:
# in collection.rb
has_many :posts,
-> { order('collectables.created_at DESC') },
through: :collectables

issue with has_many, through association

For some reason, my has_many through association isn't working. Here are my models:
class Interest < ActiveRecord::Base
has_many :evints
has_many :events, through: :evints
has_many :images, through: :events
end
class Event < ActiveRecord::Base
has_many :evints
has_many :images
has_many :interests, through: :evints
end
class Evint < ActiveRecord::Base
belongs_to :events
belongs_to :interests
end
The Evints table has three columns: interest_id, event_id, and id.
When I call #interest.events, I get the error message
uninitialized constant Interest::Events
Obviously, there's something going wrong with the association if #interest.events is being read as a constant!
Does anyone have any ideas?
Thanks!
Check your Evint class, it should be:
class Evint < ActiveRecord::Base
belongs_to :event
belongs_to :interest
end
On a different note, I think Evint isn't really a very good name. It'd suggest that you go with EventInterest, and name the table event_interests.

How to get records through a many-to-many association?

I have these models in my Rails 4 app:
class Invoice < ActiveRecord::Base
has_many :allocations
has_many :payments, :through => :allocations
end
class Allocation < ActiveRecord::Base
belongs_to :invoice
belongs_to :payment
end
class Payment < ActiveRecord::Base
has_many :allocations
has_many :invoices, :through => :allocations
end
How can I get all the invoices that are related to one particular payment X?
I've been trying to get my head around this all day but to no avail.
Thanks for any help.
As simple as:
payment.invoices
This will follow your association, passing through the allocation model.
Try this,
Identify the Payment and then its invoices like this
payment_invoices = Payment.find(payment_id).invoices

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...

Resources