Querying model by attribute of HABTM association - ruby-on-rails

I have an HABTM association between two models, User and Conversation.
I want to be able to query the logged-in user's conversations (current_user.conversations), passing it another user's id, and have it return a conversation that is shared by both users, if one exists.
(an additional perk would be to have the query create one if one doesn't exist.)
The associations are working fine, so I can access the associated objects through instance variables like #user.conversations and #conversation.users, so I could go the long way and loop through each conversation object and search the user associations in each of them... But there must be an efficient way to construct this query.
What I would like to be able to do is something like current_user.conversations.where(conversation.users.exists?(id: #user_id)) or something like Conversation.find(users: {id: #user_id AND current_user.id}).
I imagine there is an obvious answer to this, and I've been searching around here for similar questions but haven't found any. After looking through the Rails API docs, I imagine that the solution I'm looking for involves .includes() in some way, but I can't get it working.
Any advice? Thanks.

Suppose you have two users #sender and #receiver, and there is one (or perhaps more) conversation between them. One possible way to query their shared conversations is by using the merge function in ActiveRecord. merge will select the intersection of conversations between between them:
#shared_conversations = #sender.conversations.merge(#receiver.conversations)
Note that the result will be a collection, not an individual conversation. In SQL this would translate to an INNER JOIN.
If you wanted to amend this query to create the conversation if it didn't exist, then you can use first_or_create. Like its name implies, first_or_create returns the first item in the collection. If the collection is empty, it will create a new object. You can pass it a block for further control over the newly created object:
#shared_conversations = #sender.conversations.merge(#receiver.conversations).first_or_create do |conversation|
conversation.title = "#{#sender.first_name}'s conversation"
end
You can find more details on merge in the Rails docs: http://apidock.com/rails/ActiveRecord/SpawnMethods/merge.

Try
current_user.conversations.includes(:users).where(user.id:current_user.id)

Related

access ActiveRecord Has Many associations

I have a model which has a lot of associations. What I need to do is to check whether one of those associations is not present or all of them are set correctly.
To do so, I created an array which includes all of those needs-to-be-checked fields. And created a loop through each element, but the case is that I can not access has_many related attributes with read_attribute method. It basically returns nil whenever I try to access has many associated fields.
What I am trying to do, I can access all related objects via car.drivers but I can not access the same object with car.read_attribute(:drivers) (because some of them are attributes and some are relations)
I think it's the behavior of read_attribute, so what should I use to access any (attribute or relation) on ActiveRecord object?
Regarding to the comments, it looks like no one understand what I am trying to do. I want to access the relations of one ActiveRecord object such like;
RELATIONS.each do |relation|
puts "#{relation} exists" if #object.relation.present?
end
What I do not know about this, is there any method that I can access the related objects with their string typed name. Similar to, #object.read_attribute(:attribute_name) In that way I can create a for loop, but for relations not for the attributes
To do so, I used dynamical method call. Below is an example of showing it
RELATIONS.each do |relation|
puts "#{relation} exists" unless #object.send('relation').nil?
end

How do i retrieve my ratings from my database

how do i get to retrieve my ratings something like this "['G','PG','PG-13','R']" from my database through my class method in my Movie class? My database contains a list of Movies table in which the row entails "title","ratings","description","release date".
To get ratings of all movies in a single array like you mentioned you simply use:
Movie.pluck(:ratings) #assuming column name ratings
This will give results like
['G','PG','PG-13','R']
If you also want to know that which movie has which ratings then, you can modify the code to following:
Movie.pluck(:id, :ratings)
Its result will be something like:
[[1,"PG"], [2,"PG-13"], [3,"G"]]
For more information visit this link
http://apidock.com/rails/ActiveRecord/Calculations/pluck
From the fact you've tagged rails and listed what sounds like a table structure I'm going to assume you're using Rails' ORM ActiveRecord with postgresql database right? If so, you could access your ratings by using the command Movie.pluck(:ratings). This should grab all the inserts in your ratings column for your Movies table and return an array of them. You will need to implement this in one of your MoviesController actions.
If you Ratings are stored in an Array then you would had to write a function to separate all the following: "['']". It would be much simple to create an enum or give you rating an ID so when you post a movie and want to give it a rating you can call it by calling its ID or enum value.
Please check this documentation about getting specific columns. In particular de pluck method.
http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-pluck
So, you can do something like:
Movie.pluck(:ratings)
Other option is use a normal "query" structure:
#movies = Movie.select('ratings').where(...#some condition)

iOS, How to get list of parent classes with its children in Parse?

I have the table Users and the table Posts.
---Users---
id
name
---Posts---
id
text
User
How do I get the list of users, including the posts? I know how to get the list of posts with the users, because the pointer of the user is in that table. But the users does not have any pointers to posts.
What you want will be a lot of requests. You can easily query for (and paginate) the users. Then, for each user, you need to make another (paginated) request to find Posts with a pointer to that user. For that use whereKey:equalTo: with the bame of the user column on the Post and the current user instance.
Do you have a list of users already, and need to get all of their posts? If so, use the whereKey:containedIn: method. You can also create a query on users that pulls all the users you want to pull the posts for, and then rather than running the query, you create a second query on your posts objects and use whereKey:matchesQuery: which means that the object referenced in the Key is an object that would be returned by the query you pass in. So it'll return all the posts relevant to the users that would be returned from the initial query.
When you run this query, you may want to look into the query.each() method as an alternative to query.find(). query.find() is limited to 1000 results, query.each goes through every single result. This could be a problem when you scale, though, as cloud methods have a 15 second timer, and before/after save triggers have a 3 second timer.

Querying embedded documents of one given parent document

I have a mongoid model class "Event" embedding many of class "Participant". Participant has a field "email". Now somewhere in the code I get a reference to one specific Event instance named "#event".
How do I now query the participants of ONLY that instance for an participant with email = XYZ?Not all participants in the collection, just the ones of this given instance #event.
Any ideas?
Thx!
This should work
#event.participants.where(email: 'XYZ') # this will help you query what ever you want
#or
#event.participants.find_by_email 'XYZ' #this will get exactly one record

Order by association field using ActiveRecord

Is it possible to write an ActiveRecord query that sorts by an association field if the association exists, and otherwise sorts by an attribute on the object itself?
Example: I have a Discussion object which has_many :comments. I'd like to display a list of discussions sorted by discussion.latest_comment.created_at. However, some discussions may not have any comments, in which case I would like use their discussion.created_at attribute instead.
The catch is that I need the result to be an ActiveRecord::Relation (for performance reasons, and also because we are using Kaminari [which requires a Relation object]).
The only thing I could think of is to actually create a new field like discussion.latest_comment_at which would be initially populated by discussion.created_at and then updated every time a new comment is posted. However, this doesn't seem very straight-forward from a maintenance perspective (e.g. what happens when a comment gets deleted?).
I don't know of a way to do this through SQL, so I cheated and I have my code set a last_post_at attribute whenever a topic is created.
That way, I can then sort the topics by last_post_at rather than having to query two tables at once.
I've seen other forum systems do it this way too, and it seems like what you're designing is exactly a forum-like system.

Resources