I have a page that shows posts that another user makes, and I was able to make it so that if you go to the index, it only shows posts who's user_id is = to the current users user_id. But if i go to the url and change the post number, I can see other users posts and even edit them. I have tried changing the controllers show #time_sheets = TimeSheet.where(:user_id => current_user.id)find(params[:id]) and have also tried using <% if #time_sheet.user_id == #currentuser.id %> in the view, but neither seem to work. What am I doing wrong?
You can use before_filter and redirect user to home page with error message if they are trying to access a page of a different user.
before_filter :validate_user
def validate_user
timesheet_user_id = Timesheet.find(params[:id]).user_id
redirect_to :root, :alert => "Unauthorized" unless timesheet_user_id == current_user.id
end
You can read more about filters here
In controller, you should have:
#time_sheet = TimeSheet.where(user_id: current_user.id).find(params[:id])
or, if you have association user has_many timesheets:
#time_sheet = current_user.time_sheets.find(params[:id])
It should work.
BTW you should of course check if anyone is logged in before calling this piece of code.
Related
I have the following resources
Places (:place_id, :name, :shortlink, :token)
Events (:event_id, :address)
I have a restricted user registration with a nested user resource (User has many Events).
When User register, (s)he create a new event with a referenced place column.
Users can only sign up when having theses parameters in the url
https://mysite/user/signup?q=[:place_id]&t=[:token] # place id must exist, place token must be equal to t parameter
before_action :check_has_access, only: [:new]
...
protected
def check_has_access
#place = Place.find(params[:q])
if params[:q].blank? && #place.blank? || params[:t].blank? || #place.token != params[:t]
redirect_to(root_path)
flash[:alert] = 'Restricted sign-up'
end
end
I want to generate a shortcut for each place for the user to register
https://mysite/[:shortlink] #place.shortlink
That will redirect to a given sign up form with corresponding filled form and restricted params so the user that has the direct url can sign up.
https://mysite/user/signup?q=[:place_id]&t=[:token]
How can I have routes to be generated ?
Subsidiary question, am I doing it right ?
Found a solution on this post here.
I need to restart the server so newly created route get loaded after a Place object creation. Not sure if I am doing it right though but it works..
#config/route.rb
Rails.application.routes.draw do
Place.all.each do |pl|
get "/#{pl.shortlink}" => redirect("/users/sign_up?q=#{pl.id}&t=#{pl.token}")
end
end
In order to load the newly created route when adding a Place, I added
#models/place.rb
after_create :add_shortlink
...
def add_shortlink
Rails.application.reload_routes!
end
This will not work on Heroku, issue addressed is here
I have a user_id column. Instead of calling for all members how can I call up members based on current user's and user_id?
This is my controller, I tried changing .all to user_id or current_user.id plus many variations based on examples. Still can't get it. I also have no models (using authrocket). The create action also works and inserts the user_id, I have a def current_user at the bottom.
class Members::MainsController < ApplicationController
# Member Profile List
def index
#members_mains.user_id = current_user.id
#members_mains = Members::Main.all
end
private
# Common Callbacks
def set_members_main
#members_main = Members::Main.find(params[:id])
end
# White List
def members_main_params
params.require(:members_main).permit(:mfirstname, :mlastname, :mtitle, :memail, :mphone, :mnotes, :smfacebook, :smtwitter, :smlinkedin, :user_id)
end
end
If I got it right, your index action should be something like this:
# Member Profile List
def index
#current_member = Members::Main.find(current_user.id)
end
Do you intend to show a list of profiles for all members?
If not, your index action can simply be removed. If so, you wouldn't normally filter on a user_id at all for that action and you can remove that line.
To load a member profile for a specific user_id, try a show action something like this:
def show
#members_main = Members::Main.find_by(user_id: params[:id])
end
That will load a member profile based on the :id from the URL.
If you want to just show the current user's own profile instead, use current_user.id which will give you the AuthRocket user's ID.
def show
#members_main = Members::Main.find_by(user_id: current_user.id)
end
In either case, you may need to remove :show from the set_members_main callback.
Lastly, you probably want to remove :user_id from members_main_params so that users can't modify the AuthRocket user_id. You only want to control that directly (as you already are in the create action).
Hopefully that's clear enough to get you on your way, but I could be off a bit based on what functionality you actually intend for index and show.
I am new to rails, I have one model named "Topic", I want to get users those are currently viewing topic index page.
How do I get those users, can anybody help me?
Thanks in advance
Here is article which describe how to track active/online users use Redis. You can use this approach to track users who are currently viewing your page.
I would do this like so:
Similar to Jack Hardcastle's suggestion, you could have a column in the users table in your db which stores the path part of a user's url, and another column called "last_seen_at"
:string last_viewed_page
:datetime last_seen_at
Then, in your ApplicationController you could have a before_filter like this:
#in ApplicationController
before_action :set_last_seen_at_and_last_viewed_page
def set_last_seen_at_and_last_viewed_page
if current_user && request.method == :get
current_user.update_attributes(:last_seen_at => Time.now, :last_viewed_page => request.path)
end
end
The reason i test that request.method == :get is that this will only include pages that they actually load in the browser, and see the address in their address bar, and not form submission urls which are usually hidden from the user.
So, now you have the data, it's easy to query. We can never know who is on a page at this exact moment, since we don't know what they are actually doing - they might have gone to the toilet or closed their computer. We can only say that "this page is the last page these people looked at, and they did so within the last 15 minutes" or whatever.
So, if we wanted to use that criteria, of the last 15 minutes, we could say
#current_path = request.path
#users_on_current_path = User.where(["last_seen_at > ? and last_viewed_page = ?", 15.minutes.ago, #current_path])
So I have this application, where you create a user and then you can add movies and shows into a database. Like a bad version on IMDB?
Now.. I have this controller: https://github.com/Veske/form/blob/ryhm/app/controllers/movies_controller.rb
I have set up routes for movies and also it has all the necessary view files.. but when I attempt to go on a page to edit one of the movies: http://whatever.com/shows/1/edit for example, it gives me a error:
Couldn't find User with id=1
def correct_user
#user = User.find(params[:id])
redirect_to root_url unless current_user?(#user)
end
end
params
{"id"=>"1"}
Now.. why is it thinking that the param I throw at it, is a #user param when I have a update and edit controller made specially for Movies?
You don't seem to understand routes. The context in which you are using params[:id] is the movies controller, hence, the id would be the movie id. At the same time, you're authenticating (?) with the same param, giving you the error.
For basic authentication you could use the session hash, and for a more advanced one there are lots of gems, being devise the most popular.
PS: use rake routes to check your available routes and its URL params.
Your shows_controller.rb file calls correct_user before running the edit action you are calling, and it is specifically looking for a user on line 70. So it would make sense that you are getting this error if there is no user with an ID of 1.
Why is it thinking that the param I throw at it, is a #user param when I have a update and edit controller made specially for Movies?
Because you have a before_action filter at the top of your controller that is being called on the edit action.
You get into the correct_user method, which is using finding a user based on params[:id] . To test that this is your actual problem, you might want to try to change line 68 in your controller to:
#user = User.last #quick fix
The above could be used as a quick fix -you shouldn't get that error you posted about any more, as long as your user is signed in. If this allows you to avoid the error, you then need to concern yourself with properly assigning this User#id value when this correct_user method is called by your controller.
This is a MoviesController, so the params[:id] is actually the movie_id, i.e., the number "1" in your url "http://whatever.com/shows/1/edit". Not the user_id. So it throws the exception at line #user = User.find(params[:id]).
I went through your code but can't find where the correct user_id should come from. The Movie model doesn't belongs_to user. You should check out where the user come from.
I am using Devise for registering accounts and signing in/out. The next functionality I want to add is to only show the data entered for a given user. For instance, if I create a new "something" (a client in my case, at /clients/new), I only want the person who created that something to be able to view it. Right now, if I log in and create a new client, then log out and back in as a different user, I'm able to see the client I created as the other user. This should be restricted so that the author is the only one who can read, update and destroy their own clients.
I've watched Ryan Bate's screencast on CanCan 3 times now, but it seems to only touch on setting it up for different roles, and not for limiting content based on the author.
How can I go about this with CanCan?
My current ability.rb has nothing in it but an empty initialize(user) method.
I have tried this inside that method:
can :update, Client do |client|
client.try(:user) == user
end
with
<% if can? :update, #client %> ... <% end %>
around the loop that displays the clients in the index view, but to no avail.
I think that filtering the results using CanCan is not an optimal solution.
If User 'has_many' Clients, then in your controller method just query for Users' clients:
#clients = current_user.clients
Give this a try
def initialize(user)
can :update, Client, :user_id => user.id
end
From cancan wiki