I have 2 models in my Rails 3 app
User:
class User < ActiveRecord::Base
acts_as_followable
acts_as_follower
has_many :posts
end
Post:
class Post < ActiveRecord::Base
belongs_to :user
end
So, I can fetch users that I follow: User.find(1).following_users
But how to fetch posts of followed users? Something like User.find(1).following_users.posts
User.find(1).following_users just returns and arel reference, see here:
https://github.com/tcocca/acts_as_follower/blob/master/lib/acts_as_follower/follower.rb#L59
So,
User.find(1).following_users.includes(:posts)
should include the posts for the users in the query, but this will return an array of users. The following should work, loop through the users that are returned and collect their posts into an array
posts = User.find(1).following_users.includes(:posts).collect{|u| u.posts}.flatten
User.following_users.collect{|u| u.posts}
This should work
Related
I'm facing an Rails (and finally a pur SQL) issue.
I have 3 tables (models). Event / User / Invitation
class Event < ApplicationRecord
has_many :invitations
end
class User < ApplicationRecord
has_many :invitations
has_many :events, through: :invitations
end
class Invitation < ApplicationRecord
belongs_to :event
belongs_to :user
end
I want to list all events where a specific user does not have invitation.
Contraints (very important in my case):
I'm starting my request by Event.
Basically, I would say it's the opposite of a merge, like a merge.not(user.events).
The only solution I found is:
Event.where.not(id: user.events.pluck(:id))
But obviously, I don't like it. 2 queries that might be somehow merge into a single one.
Any idea?
use select instead of pluck, it will create sub-query instead pulling records from database. Rails ActiveRecord Subqueries
Event.where.not(id: user.events.select(:id))
I am trying to create a query in Rails but am having some trouble creating the correct one. Below is my models with their relationships.
class User < ActiveRecord::Base
has_and_belongs_to_many :rsvps, class_name: 'Event'
has_many :albums
end
class Event < ActiveRecord::Base
has_many :albums
has_and_belongs_to_many :attendees, class_name: 'User'
end
class Album < ActiveRecord::Base
belongs_to :user
belongs_to :event
end
I need to get all events a user has "rsvp'ed" to that they haven't uploaded an album to yet. I can find out if a user has uploaded an album to a particular event using the following:
u = User.find(1)
e = Event.find(1)
e.albums.where(user_id: u.id)
I want to be able to run this query on each of the user's rsvp'ed albums. I know I could do something like this:
u.rsvps.delete_if { |e| !e.albums.where(user_id: u.id).blank? }
However, I want to do this all in one query instead of getting the rsvps and then iterating over them and deleting them when necessary.
In order to get all events a user has rsvp'ed to but haven't uploaded an album to yet, you can use the following, which (UPDATE) now also works when a user has not uploaded any albums.
#event_ids = Album.where(user_id: u.id).pluck(:event_id))
#event_ids.empty? ? u.rsvps : u.rsvps.where("id not in (?)", #event_ids)
In addition, this query should work as well.
u.rsvps.where.not(id: Album.where(user_id: u.id).pluck(:event_id))
I'm adding quiz functionality to the twitter app from the Hartl tutorial and have these Models:
User is nearly the same as the tutorial:
class User < ActiveRecord::Base
has_many :followed_users, through: :relationships, source: :followed
has_many :takens, dependent: :destroy
has_many :questions, through: :takens
end
Taken is a table of Question ids to User ids:
class Taken < ActiveRecord::Base
belongs_to :user
belongs_to :question
end
nothing interesting in Question:
class Question < ActiveRecord::Base
attr_accessible :category, :correct, :option1, :option2, :option3, :qn
end
I want to be able to show followed_users and followers in order of the number of tests they have taken. In the console this can be had through:
User.find_by_id(1).question_ids.count
Then I can do something like:
User.find_by_id(1).followers.first.question_ids.count
in the console to get the count for a single follower.
I feel like I'm almost there.
How do I sort the followers and followed_users through their 'takens' count? (I was also looking at cache_count, which at first seemed promising, but might not be what I need...)
Ruby on Rails does not provide an object oriented mechanism to perform this; you have to write the SQL yourself. In your case, I'd say that the following line SHOULD work:
User.find_by_sql("SELECT users.*, COUNT(questions.id)
AS c FROM users, questions WHERE questions.user_id = users.id
GROUP BY users.id ORDER BY c DESC")
I don't have the actual tables in front of me, so I can't be sure that this is actual valid SQL, but hopefully it should work.
EDIT: There were a few syntax errors with my SQL but they've been fixed. Note that I'm assuming that your tables are called users and questions. They may differ for you.
I'm developing a blog site for practice. My problem is I can't call data from one object to another related object.
Here are my model associations:
1 class Post < ActiveRecord::Base
2 belongs_to :user
3 end
1 class User < ActiveRecord::Base
2 has_many :posts
3 end
In the console:
user = User.find(1)
user.posts // Everything works! It shows me a list of posts related to the user.
user.post(1) //This doesn't work! Is it wrong?
I've been looking over active record query interface guide at rubyonrails.org and still can't find anything in reference to this. Maybe I missed something?
Thanks
Do it this way:
user.posts[0] #=> returns the user's first post
assume we the following setup:
class Post < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
assume further the user has a boolean attribute 'admin', which indicates if he is a global admin or not.
I want to write a method (or a scope?) for the User class, called 'visible_posts'. If the user is no admin, it should return just its own posts. If he IS admin the method should return all posts in the system.
My first attempt was something like this:
class User < ActiveRecord::Base
[...]
def visible_posts
if admin?
Post.all
else
posts
end
end
end
Problem here is that Post.all returns an Array, but I would rather like to have an ActiveRecord::Relation like I get from posts to work with it later on.
Is it somehow possible to get an ActiveRecord::Relation that represents ALL posts ?
You can do Post.scoped i guess in Rails
And later on this you can call .all to fetch the results