Reputation: 51
I've been struggling with this for a while now, so I thought I'd ask the experts.
I am trying to make it so that Users can only edit/view Items that they have created using Devise.
I have Users set up and working well. Items are being created with a user associated with them and I can verify this via rails console.
def create
@item = Item.new(params[:item])
@item.user = current_user
end
What I am trying to do now is to make it so that once logged in, users can only see the items that they have created, and no others.
In my Items controller have tried replacing:
def index
@items = Items.all
end
with
def index
@items = current_user.Items.find(params[:id])
end
but this doens't seem to work for me and I get
undefined method `Items' for #<User:0x007fdf3ea847e0>
Can anyone offer any advice as to what to try next?
Thanks so much.
Upvotes: 0
Views: 1589
Reputation: 1304
If I'm understanding your question, I think you might want to check out an authorization library - like CanCan to do this.
https://github.com/ryanb/cancan
It works pretty slick to handle permission type things like this. Many people use this library in conjunction with Devise.
Upvotes: 1
Reputation: 4539
Maybe I`m old school but I would not use current_user to find records, only to verify permissions. I would use the primary key relationships directly (they don't change):
@items = Item.find(:all, :conditions => { :user_id => current_user[:id] }
or
@items = Item.find_all_by_user_id current_user[:id]
As for setting permissions, devise actually doesn`t let you do that BUT there is the excellent supplement called Cancan, you should definitely look into it. With Cancan, you will have an ability.rb class that will define your permissions. What you are looking for then becomes:
class Ability
can [:read, :show, :edit, :update, :delete, :destroy], Item do |item|
item.user_id == user.id
end
# or
can :manage, Item do |item|
item.user_id == user.id
end
end
reading the Cancan docs would clarify the code above.
Upvotes: 2
Reputation: 57
What you're trying to do is really close…
current_user
is an "instance" of the User
class.
What you want to do is use the association from the user instance, which is a special method applied to every user—"items
". (If the Item
class also has a belongs_to :user
it'll have a method called user
as well)
You want current_user.items.find(params[:id])
Also, when you create it, you could also use current_user.items.create(params[:item])
Upvotes: 1