views:

44

answers:

4

I've got a view for entering / editing posts.

I want to stop people from creating or editing posts if they are not logged in (in the model) & I want to redirect the ./posts/new view to the posts list with a "You cannot create new posts if you're not logged in" message.

I've tried changing the "new" command in the posts controller as so:

  def new

    if !session[:user] 
      redirect_to(@posts, :notice => 'You cannot create a post unless you are logged in.')
      return
    end

    @post = Post.new

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

but that doesn't work.

I don't know if I should put the logic for what I want to do in the controller, in the view or in the model. (Or some combination of all 3).

I'm guessing that I should only be putting it in one place (DRY, etc), but I don't know where.

+2  A: 

Try using a before_filter :verify_authenticated. Check out the documentation on the API: http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html. The second example is exactly what you're looking for. You authentication check can go into your ApplicationController so you've got it in one place.

Or check out "prettier" notes from the guide: http://guides.rubyonrails.org/action_controller_overview.html#after-filters-and-around-filters

Jarrett Meyer
Does this stop models from doing things models are not allowed to do? Or do people not worry about adding authentication to the models?
seanyboy
You don't even get to the model. The before_filter will fire before the action. You won't even get to your `@post = Post.new` line of code.
Jarrett Meyer
+1  A: 

User authorization is usually handled in controller, more specifically using a before filter. For example:

class SomeController
  before_filter :authorize

  # the rest of your controller

  private
  def authorize
    # authorization code
  end
end

Now, authorization code really depends on what gem/plugin you are using (or if you have implemented your own user system).

Slobodan Kovacevic
+1  A: 

[disclaimer: from your question it was not clear at what level of rails knowledge you are]

I am not sure where you are in this stage. I am assuming you assume rails should support authentication out of the box. It does not. There do exist a lot of plugins for this. I suggest you take a look at devise.

It does everything you need, no need to roll your own authentication. But if you really want to do it yourself, take a look at this introduction. It is very old, but most of it still stands.

But i would definitely advise to go with an existing, proved and tested plugin, like devise (but others definitely exist).

nathanvda
A: 

Some sort of declarative authorisation - like CanCan would be best suited here:

You might be better off using this rather than writing filters on controllers, since you can control the authorisation on a per-resource basis.

Omar Qureshi