简体   繁体   中英

Rails 4 : Current user can only edit their post

User is only able to edit when they are logged in but the problem is any user logged in can edit other users content. How to make user specific edit, only the current user can only edit their content?

class JobsController < ApplicationController
    before_action :find_job, only: [:show, :edit, :update, :destroy]
    before_action :authenticate_user!,except:[:index]

    def show
    end

    def update
        if @job.update(jobs_params)
            redirect_to @job
        else
            render "Edit"
        end
    end 

    private

    def jobs_params
        params.require(:job).permit(:title, :description, :company, :url, :jobcategory_id)
    end

    def find_job
        @job = Job.find(params[:id])
    end
end


show.html.haml                                            
- if user_signed_in?
    = link_to "Back", root_path, class: "btn btn-sm btn-default"
    = link_to "Edit", edit_job_path(@job), class: "btn btn-sm btn-default"

You have not associate Job with User . without it how you can identify which Job is posted by which User ?

For that associate Job with User

in user.rb

has_many :jobs

in job.rb

belongs_to :user

then add user_id column to Job table and also add user_id in your strong parameter.

To add user_id column in your Job table:

rails g migration AddUseridToJob user_id:integer
rake db:migrate

In your template: jobs/_form.html.haml assign user_id

=  f.hidden_field :user_id , :value => current_user.id

by this when user create the job in data it will be associated with that particular User So you can identify and restrict some actions.

After follow the above steps Try this:

- if (user_signed_in? && (current_user.id == @job.user_id))
    = link_to "Edit", edit_job_path(@job), class: "btn btn-sm btn-default"

Note:

  • First Create new Job after sign_in and then check that edit action link will be not seen to any other user.
  • If you try to check for existing job(old jobs) then you may get an error as existing job's data may not contain user_id
  • This will only hides the links of edit.
  • You can use cancancan gem for authorization

If you do not want to allow anyother user to edit / update / delete job and redirect them to index page then implement job_owner method like this:

class JobsController < ApplicationController
    before_action :find_job, only: [:show, :edit, :update, :destroy, :job_owner]
    before_action :authenticate_user!,except:[:index]
    before_action :job_owner, only: [:edit, :update, :destroy]
    ....
    # add this method                         
    def job_owner
     unless @job.user_id == current_user.id
      flash[:notice] = 'Access denied as you are not owner of this Job'
      redirect_to jobs_path
     end
    end
    ....                                        
end

I suggest to use cancancan gem and define your ability as below:

 can [ :edit, :update, :delete ], Job do |job|
   job.user_id == user.id
 end

You can create a helper method:

def user_allowed
  user_signed_in? && (current_user.id == @job.user_id)
end

And then call it before your actions:

<% if user_allowed %>

You probably want something like this?

= link_to "Edit", edit_job_path(@job), class: "btn btn-sm btn-default" if @current_user.id == @job.owner_id

Note that owner_id is something I made up. You haven't given enough context around what a user can/can't edit. How do you determine if a job belongs to a user or is editable by them. That should give you something to go on though.

You probably want to investigate some sort of authorization gem like pundit . Pundit will allow you to setup policies per controller and allow you to manage access with fine granularity. The documentation describes how to set it up and use before_action's to validate authorization prior to the action being run.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM