Rails 3, help controlling access to a record based on the user id

Hello, I’m a Rails newbie… Here’s what I’m trying to do…

I created a scaffold for notes (t.text :content, t.integer :user_id)
What I want to do now is only allow user’s to view notes that they
created. ie (== user_id)

In my /app/controllers/notes_controller.rb

I have the following:

class NotesController < ApplicationController
  before_filter :authenticate
  before_filter :correct_user
.
.
.
def correct_user
  @noteuserid = Note.find(:conditions=>["note.user_id=?",

@noteuserid])
redirect_to(root_path) unless current_user?(@noteuserid)
end

I’m having problems understanding how to write the following line:
@noteuserid = Note.find(:conditions=>[“note.user_id=?”, @noteuserid])

Right now I’m using the system in the Rails 3 Tutorial Book:
railstutorial.org/chapters/sign-in-sign-out#sec:current_user

Seems like the problem is current_user is an object, not an ID… Not
sure how to make the two comparable?

Thanks

This hack ends up working. Is there a cleaner, ruby trick to getting
this to work?

  @note = Note.find(params[:id])
  @note_userid = @note.user_id
  @current_userid = current_user.id
  redirect_to(root_path) unless @current_userid == @note_userid

thxs!

The cleanest method is to scope your notes by user instead of
searching the whole class:

@note = @user.notes.find(params[:id])

Ed thanks for the reply. I’d love to hear more… I tried your
suggestion but it error’d:

“undefined method `Notes’ for nil:NilClass”

On Sep 5, 10:53 pm, nobosh [email protected] wrote:

Ed thanks for the reply. I’d love to hear more… I tried your
suggestion but it error’d:

“undefined method `Notes’ for nil:NilClass”

Two possible issues:

  1. Do you have the relationship declared in the models?

class Note < ActiveRecord
belongs_to :user
end

class User < ActiveRecord
has_many :notes
end

  1. If @user is a nil object, it will throw an error. Set @user to
    the current_user in your before_filter. If there is a possibility of
    hitting that point with a nil user, then change the line to read
    something like this:

@note = @user ? @user.notes.find(params[:id]) : nil

which is a shorter way of saying

if @user.nil?
@note = nil
else
@note = @user.notes.find(params[:id])
end

Thanks for the reply, I do have the relationships declared above in
the models… I’ve been learning and following the rails 3 book here:
http://railstutorial.org/chapters/a-demo-app#sec:microposts_resource

I tried your suggestion "@note = @user ?
@user.notes.find(params[:id]) : nil " and while it didn’t error which
was good, it didn’t work, it ended up redirecting… Full code:

class NotesController < ApplicationController
before_filter :correct_user, :only => :show
.
.
.
def show
@note = Note.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @note }
end

end

private
def correct_user
#@note = Note.find(params[:id])
#@note_userid = @note.user_id
@note = @user ? @user.notes.find(params[:id]) : nil
@current_userid = current_user.id
redirect_to(root_path) unless @current_userid == @note_userid
end
end


Any ideas? I want to learn the right way to Rails

please check the post “Use scope access” on rails-bestpractices.com,
http://rails-bestpractices.com/posts/3-use-scope-access, it tells you
how to use the Ed’s way to strict access and rescue the exceptions.

Thanks all, this ended up working which I believe scopes correctly…
Thoughts?

@note = current_user.notes.find(params[:id])

On Sep 6, 3:04 am, Frederick C. [email protected]

On Sep 6, 4:38 am, nobosh [email protected] wrote:

            def correct_user
                    #@note = Note.find(params[:id])
                    #@note_userid = @note.user_id
                    @note = @user ? @user.notes.find(params[:id]) : nil
                    @current_userid = current_user.id
                    redirect_to(root_path) unless @current_userid == @note_userid

You don’t seem to be setting @note_userid anywhere. The check is
redundant though - doing @user.notes.find(…) ensures that the
returned note (or notes) have a user_id that is @user.id. You
obviously need to set @user to somethign first (or if current_user is
set appropriately by your authentication stuff then you could do
current_user.notes.find(…).

Fred