Question

The following is a standard posts#create action (app/controllers/posts_controller.rb).

At the controller level, I want to prevent an anonymous user (a user who is not signed in) from being able to save a post. As a secondary objective, I don't even want to execute the Post.new line if the user is not signed in. I want to know what is the best practice for accomplishing this.

Also, as a side note, I am unsure of how to write the json portion of the response. If I am redirecting with an alert message in the HTML context, what would be a good thing to respond with in JSON world?

def create

  @posting = Post.new(posting_params)

  respond_to do |format|

    if @posting.save
      format.html { redirect_to @posting, notice: 'Post was successfully created.' }
      format.json { render action: 'show', status: :created, location: @posting }
    else
      format.html { render action: 'new' }
      format.json { render json: @posting.errors, status: :unprocessable_entity }
    end
  end
end

For the time being I have the following line in my code, above the Post.new line:

redirect_to home_path, warning: 'You must be logged in to post.' and return unless user_signed_in?

I suppose another option is something like the following, placed above the if @posting.save line. But really, I am looking to see what other folks would do.

unless user_signed_in?
    format.html { redirect_to home_path, alert: 'You must be logged in to post.' and return }
    format.json { render json: .....not sure what to put here..... }
end

Your advice is greatly appreciated.

Était-ce utile?

La solution

A before_filter is good for this sort of thing:

before_filter :confirm_user_signed_in, only: [:new, :create]

def confirm_user_signed_in
  unless user_signed_in?
    respond_to do |format|
      format.html { redirect_to home_path, alert: 'You must be logged in to post.' and return }
      format.json { render json: .....not sure what to put here..... }
    end
  end
end

As far as what to render in the JSON scenario, you can render nothing at all, but with a 403 (Forbidden) status. You can optionally include some data explaining why the 403 occurred, but there's no standard for how that data will be displayed. Some frameworks (Backbone, I think) will look for a hash containing an errors key, which can be set to the reason.

Something like:

format.json { render json: { errors: ["Login required."] }, status: 403 }

Autres conseils

The better practice is to use before filter and mention list of actions like this:

before_filter :require_login, :only => [:new, :create]

Try using the cancan gem. You can not only prevent the unwanted user from posting, also you can do various other permissions, which do not bloat the controller. These permissions are defined by you in a separate file called ability.rb.

cancan Railscast

cancan Github

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top