Find last record for specific user (Rails) - ruby-on-rails

I want to do something like Report.last, but instead of the last record entered, I want the last record that a specific user entered.

You are probably looking for something like
Report.where(created_by_id: user_id).last
where the key in the where clause is the foreign key in a reports table record to the association with the user. I'd have to know how your models associate reports with their creators to know the right syntax.

You need to include the user_id or some sort of user indicator to be able to get the last record for a specific user. You will need to post more information like the model for your users and reports. But I think you are looking for something like this:
Report.select([:user_id, :id, 'MAX(created_at)']).group(:user_id).limit(5)

user = User.where(:some_condition => "some_value").first
user.reports.last
This would work if user is a local variable representing an active record user and records would query its associated records and find the last one.

I assume you have model relationship between User & Report
user = User.first
user.reports.order("updated_at DESC").last

Related

Active Record Where Clause For Relation In Model

I have two Models User and Site. The User has category like 'basic and premium'. The user has relation to sites one -> many (i.e one user can have more than one sites). Now i want to select sites of premium user. Can someone tell me how to use where clause in ActiveRecord to achieve this?
I want to select sites of premium user
This will do
User.includes(:sites).where('users.category = ?', 'premium')
Update
If sites also have categories like 'wordpress or joomla', how do i
apply where clause to select only wordpress sites of premium users
For that you need to tweak the query like this
User.includes(:sites).where('users.category = ? and sites.category = ?', 'premium','wordpress')
As you said that category is a column, so Rails automatically generates the following method for you:
User.find_by_category("basic")
If you do not want to use this, you can use where method, in which you have to send a key-value pair like following:
User.where(:category => "basic")
And when you have found a user with the category you desired, you can simply call sites on it to get all the associated sites with a particular user.
You can try this also:
#user_ids = User.where(category: 'premium').pluck(:id)
#sites = Site.where(user_id: #user_ids)

Add email model that allows for one primary and multiple secondary email addresses

In Rails, I want to create a model email that allows for polymorphic associations from different people, say 'users' and 'admins' so that they 'has_one' primary_email and 'has_many' secondary_emails.
Is there a way to do this under one model called Email?
I was thinking of creating an Email model that has a column for primary_email:text and another column secondary_email:array (of emails).
I feel like there is a better way to do this though.
EDIT
Now I am thinking of creating a simple Email model with just one email column (and emailable_id and emailable_type columns as well). Then User will "has_many" emails. Now I am a little confused as to how the relations work. Right now a user already has an email column. Can anyone think of a way to consider this their primary email in the User model. Then if the user already has a primary email, create a secondary email.
To be clear
I want all of the emails to be part of the Email model, and the distinction between primary and secondary emails to be made in the User model.
Can anyone think of a way to do something like that?
Thanks!
If I were to do this, I would go for an array attribute using the serialize method. (See this post and this tut.)
Remember that has_many is an association between two models, so it is definitely not possible to use it with only one model. But there is also nothing wrong with creating a second model for storing only one email, and using has_many

The way to implement User Email Preferences?

I want to implement a feature which lets every user decide the kind of emails he/she will receive. So far, I can only see the user receiving emails when he/she receives a friendship request and when he/she receives a new message. The way I plan to implement this is as follows:
Each User has_one EmailPreference
EmailPreferences table will have 2 columns: Friendship (Boolean) and Message (Boolean).
By default, they will be true. So the User will receive emails for both new messages and new requests received.
The user can go to the Edit action and update the values as per his choice.
I plan on using an if statement which will check if #user.emailpreference.message? or #user.emailpreference.friendship? before the send email method.
I'd like to know if this is the best way to go about it.
A couple considerations - I'd question whether you want to do the has_one or simply add the columns to the user. I also tend to use dates instead of booleans, so you can see when the boolean was set. For naming, consider something other than 'friendship' and 'message'. If it is an attribute on the user, I'd consider something like 'subscribed_to_friendships' and 'subscribed_to_messages'.
The reason I avoid has_one's in general is to make very simple queries and reduce the need for maintenance. It's likely you'll be getting all users that should receive a message and looping through them, I prefer to avoid the joins and keep it simple. I also don't really like how false and null are the same on the child. This will help you avoid deleting/adding preference records, especially if the default is true and you're going to create preferences for most users by default.
I see one issue in the approach is that if tomorrow you have more type as preference , means when somebody joins than also you want to send the email , in that case you have to add one more column. Why do not you normalize it further and use more table to store the Preference type
Id Name
1 Friendship
2 Message
Id User Id Flag
1 1 TRUE
2 1 False
It means user 1 is opted for Friendship but not for Message. Now you can easily add any new preference.
the approach by https://stackoverflow.com/users/177489/swards is for me , the best option because that has_one queries can be a mess later.
add columns to user model and gg!

rails 3 associations with join table query using active record

I have three models which are User, Domain and Association. My user model is populated from devise. My Domain model consists of "People's interests such as - running, biking etc". My association table links a user_id to a domain_id and stores it as a record. When I add a domain it automatically populates the user sign up form with domain's (in which a user can pick e.g. I like running).
My Query is.. What active record query could I use to pull user's with the similar interests e.g. running, with the currently logged on user. So if a user called Tom was logged in and had select domain interests of running and biking (linked to), how could I pull back a database object with other users that had the similar domain's (interests)
So basically if Tom, Paul and Steph were users, but Tom and Paul selected the same domain's and Steph selected different ones, what would be the Query code to do this? Hope this is enough information.
I think you could do something like this:
User.joins(:domains).where("domains.id IN (?)", current_user.domains.pluck(:domain_id))
current_user.domains.pluck(:domain_id) collects all the domain ids that the current_user has selected. Pluck is only in rails 3.2, if you're using an earlier version, you'll have to use collect instead.
Then the first part of the query selects the users who also have that domain as one of their interests.
You should look at the rails guide as Bongs suggests
http://guides.rubyonrails.org/association_basics.html

Ruby on Rails - Optional Associations?

I would like to allow users to write comments on a site. If they are registered users their username is displayed with the comment, otherwise allow them to type in a name which is displayed instead.
I was going to create a default anonymous user in the database and link every non-registered comment to that user. Would there be a better way to do it?
Any advice appreciated.
Thanks.
The problem with creating an anonymous user is then you need to check if a comment was made by a "real" user, or an anonymous one when displaying the name, so that introduces complexity. Plus, if you have a way of viewing their profile page, which may include posting history, you'd need to exclude the anonymous user with an exception.
Generally it's better to have a column on your comments which represents the user's visible name, and just show that if provided, or the registered user's name otherwise. For instance, your view helper might look like this:
class Comment < ActiveRecord::Base
belongs_to :user
def user_name
self.anonymous_name or (self.user and self.user.name) or 'Anonymous'
end
end
This will display the contents of the anonymous_name field of the Comment record, or the user's name if a user is assigned, or 'Anonymous' as a last-ditch effort to show something.
Sometimes it's advantageous to actually de-normalize a lot of the database when dealing with large numbers of comments so you don't have to load in the user table via a join simply to display a name. Populating this field with the user's name, even if they're not anonymous, may help with this, though it does mean these values need to be updated when a username changes, presuming that's even possible.
I think you can make user_id on your comment model nullable since you want to allow non registered users to add comments as well. As far as adding names for the non registered users are concerned, there are two options for that
option 1. Add a column on Comment model and name it like anonymous_user where you will store names of non registered users
option 2. Create a another model AnonymousCommentor with name and comment_id attributes.
If you are going to use anonymous users for other things as well apart from comment in your application then you can make it polymorphic and use a suitable name like AnonymousUser instead of AnonymousCommentor

Resources