I've got it so that the show view on a customer's page links to all the orders that they have placed. When they click "Show", it takes them to the show view for that order. However, if they were to change the id of the order in the url, they can then see other people's orders. Please can someone help or suggest ways in which I can have it so that if someone was to try and view an order other than the one they have been directed to, they will be redirected to their customer page? I can get the redirect bit working fine, using:
redirect_to customers_path(session[:customer_id])
but how would I get the application to make sure that the customer can only view that order? I can't seem to use the sort of logic where I check that the order id equals the order id in the url, as that will always prove true!
Assuming than your Order model has some concept of "who owns this order," usually via an integer column called something like user_id
, you can check to see if session[:customer_id]
is equal to order.user_id
(or whatever you call it).
You will generally keep this authorization code in your controllers.
class OrdersController
...
def show
@order = Order.find params[:id]
unless session[:customer_id] == @order.user_id
flash[:notice] = "You don't have access to that order!"
redirect_to customers_path(session[:customer_id])
return
end
end
...
end
As your application gets more complicated, you might look into authorization gems like CanCan to handle this logic.
I recommend adding an authorization gem such as CanCan, which lets you set whether the user has access to do certain things (e.g. edit an order, view an order, etc.). This may come in handy in a lot of ways; you may want to have admin pages (for adding new products, say) that customers should never have access to.
Once you have that in place, you can restrict a customer's access so that they can only view or edit their own orders. In CanCan, you create a class called abilities.rb that looks something like:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can [:read, :update], Order, :user_id => user.id
end
end
end
That bit about can [:read, :update], Order, :user_id => user.id
means "the (non-admin) user can read or update an Order if the order.user_id == user.id" (i.e. the current user's id).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With