Rails 4 : 当前用户只能编辑他们的 post

Rails 4 : Current user can only edit their post

用户只有在登录后才能编辑,但问题是任何登录的用户都可以编辑其他用户的内容。如何让用户特定编辑,只有当前用户才能编辑他们的内容?

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"

你可能想要这样的东西?

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

请注意,owner_id 是我编造的。您没有就用户 can/can 未编辑的内容提供足够的上下文。您如何确定作业是属于用户还是可由他们编辑。不过,这应该能让你有所作为。

您可能想要调查某种授权 gem,例如 pundit。 Pundit 将允许您为每个控制器设置策略,并允许您细粒度地管理访问。该文档描述了如何设置它并使用 before_action 在操作 运行 之前验证授权。

您还没有将 JobUser 关联起来。没有它,您如何识别哪个 Job 是由哪个 User 发布的?

对于 JobUser

的关联

user.rb

has_many :jobs

job.rb

belongs_to :user

然后将 user_id 列添加到 Job table 并在强参数中添加 user_id

要在 Job table 中添加 user_id 列:

rails g migration AddUseridToJob user_id:integer
rake db:migrate

在您的模板中:jobs/_form.html.haml assign user_id

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

这样,当用户在数据中创建 job 时,它将与特定的 User 相关联,因此您可以识别和限制某些操作。

完成上述步骤后试试这个:

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

注:

  • 首先在 sign_in 之后创建新作业,然后检查 edit 操作 link 不会被任何其他用户看到。
  • 如果您尝试检查现有工作(旧工作),那么您可能会收到错误消息,因为现有工作的数据可能不包含 user_id
  • 这只会隐藏 link 的编辑。
  • 可以使用cancancan gem进行授权

如果您不想让任何其他用户进行 edit/update/delete 作业并将他们重定向到索引页面,请执行 job_owner 方法,如下所示:

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

我建议使用cancancan gem并定义你的能力如下:

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

您可以创建辅助方法:

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

然后在你的操作之前调用它:

<% if user_allowed %>