Rails 4 proper way to prevent wrong user creating likes - ruby-on-rails

I tried to find this on google but can't seem to find anything on this. I have a model called Likes, along with a controller which simply belongs to an Event and a User. I would like to prevent people from creating a Like when they're not logged in, and not allow them to create a like for another user. What is the proper way to do this?
Thank you

When you have a user based system, all queries related to user-owned data need to include the user, or originate from it. Most authentication systems have a helper to get the current user, often called current_user.
Assuming some things about your model, for "liking" an event, you could do it a couple ways:
current_user.likes.create(event_id: params[:event_id])
Like.create(event_id: params[:event_id], user: current_user)
Validations can help as well, making sure event and user IDs are always present. If no user is logged in, this should make it fail, assuming someone guessed the path to try and manually create a like.

Related

Best approach to check a model's value against a simple list

I have a Rails user model with an email field. I want to check whether the user's email is on a list of emails. Let's call it the "Guest List." I'm looking for the cleanest way to keep the guest list and check if the user is on it.
This could be an externally-maintained list (a Google sheet, CSV, etc). Or it could certainly be a table in the Rails app's database.
I was going to create the table, but I don't know the preferred way to do that for such a small task. Should I actually be creating a whole new model for Guest List? It seems like a very high-level thing to create for this one task. The Guest List will never be used for anything other than
if GuestList contains user:email
do something
end
Any advice? Does Rails have some other feature that is good for this?

Rails User tracking activity

I want to track user activity on site. I tried ActiveSupport::Notifications but hasn't user_id or something to define a user. As I see, there are 2 ways to do this: through ActiveRecord queries, and through Page Requests. In the first case I should subscribe to all possible user actions with model (after_create, after_destroy etc.), and I have about 20 associated models, that is a lot of duplicate code. The second - I don't know how to do this, but it's seems simply to me.
I'm not using Device or any gem.
Perhaps in the first way, I could include module and make all logic in it, but It's not working.
The problem was solved by adding before_filter :track_activity in ApplicationController, ti calls every time when user enter any page.

Keeping POST data during sign up with Devise

I might be approaching this problem the wrong way ... so if you have a more elegant solution I'm all ears.
Imagine I'm making a system like Kickstarter. I want my users to be able to specify how much they want to pledge before I ask them to sign up.
Then, if they're not registered I need them to sign up before putting them back in the flow that they would have been on had they just signed in. Devise makes this easy by redirecting a user back to the after_sign_up_path_for which ends up being after_sign_in_path_for by default.
So this will always issue a GET request. But if I have data that I received from the POST with the amount they wanted to pledge, but that's lost.
Is the only way to do this to store that posted data in the session? Or is there a clever way to start creating the pledge record without the user (without needing to run jobs to destroy orphaned pledge records)?
I found the approach described in this blog post over at highgroove.com quite interesting in this regard: 
http://highgroove.com/articles/2012/10/09/lazy-user-registration-for-rails-apps.html
The basic idea is to always have an anonymous user at hand, even if the current vistor is not registered. Like this you can create e.g. associations as usual and — once the visitor actually does sign–up — you edit the user rather than all associated objects.
If the user does not ever register, you can simply look for abandoned user accounts and delete them including their associations, rather than look for all kind of abandoned models.

How do you model an anonymous user in an existing Rails schema?

I'm working on my first simple Rails app in which users submit sport "tweets" (e.g. "tennis, squash") and the server matches them up with partners. The server will return you a list of SportMatches based on similar tweets and you have different options (e.g. email, SMS) to reply back to someone's tweet and accept him/her as partner. Initially, the modeling was straight forward since: User has_many SportTweets and SportTweet belongs to User. Notifications were simply part of the User, or they could have been modeled as a 1-to-1 relationship to User.
My business requirements changed a little, as now I have anonymous users who can also post SportTweets. Because they don't have an account/profile, they must also submit notifications (e.g. email, SMS) with the tweet. I don't know how to model this the Rails way. SportTweets are now either anonymous, or authenticated-user-posted (AUP). So, now, my SportTweets table will have the following columns:
type: either "anonymous" or "AUP"
user_id: only for AUP
notifications_id: only for anonymous
sports: for all
post_date: for all
post_location: for all
etc.
There would be a Notifications table. A notification record would belong either to a User, or to a SportsTweet. I guess I would model this with polymorphic associations.
That just doesn't look like the Rails way. Did anyone come across a similar problem? How did you solve it?
Did a bit of searching and the answer is STI. See The Rails 3 Way - Chapter 9.
Use Devise if you can. I think this link might help you.
In some applications, it's useful to have a guest User object to pass around even before the (human) user has registered or logged in. Normally, you want this guest user to persist as long as the browser session persists.
Our approach is to create a guest user object in the database and store its id in session[:guest_user_id]. When (and if) the user registers or logs in, we delete the guest user and clear the session variable. A helper function, current_or_guest_user, returns guest_user if the user is not logged in and current_user if the user is logged in.
Followed by the code which you might find helpful in that page

Ruby on Rails private link sharing: Google Docs Style

What would be the best way to go about giving users the ability to share a private link that enables anyone who clicks it to view a certain page/document/item that have privacy restrictions in place?
In my case:
A User creates events which are limited to certain groups of relationships in the database (namely: friends, friends of friends, etc.) I have a :before_filter in the event controller that checks the eligibility of the current logged in user to make sure that that user has permission to see the event. If they don't they get booted to the root page with an error message.
However, I want a special scenario to exist where a user can create an event with those same privacy settings and IN ADDITION, be able to share a special link with his or her friends via e-mail, facebook, etc. Those users do NOT need an account (but will need to make one in order to sign up for the event). This is important because there is also a :before_filter in the application_controller which makes sure a user is logged in.
I'm thinking there is something I could do with routing here... Right now I just have the simple /events/72 setup. Should each event have two different links: a normal one, and a "special code" version which enables them to bypass those two :before_filter?
What are people's thoughts?
I agree with David Lyod's answer (separating this concern in a different controller).
But for creating the hash I strongly recommend you salting the hash with some secret phrase.
require "digest"
Digest::SHA512.hexdigest("#{created_at}#{user_id}.mysupersonicsecretSALT")
Doing this it is not possible, without the knowlegde of the secret phrase, to calculate the hashes and test them against your system until it hits an existing one.
If you're handling sensitive data you should not be lazy.
Cheers,
Lukas
I would have a separate controller that uses a hash value to reference the event.
Something simple like the created_at + user_id hashed to create a unique reference.
You could also simply skip the check on a certain action but I would much prefer the first solution .

Resources