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

时间:2015-04-23 12:27:52

标签: ruby-on-rails devise

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

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"

4 个答案:

答案 0 :(得分:14)

您尚未将JobUser相关联。如果没有它,您如何识别哪个Job由哪个User发布?

该合作伙伴JobUser

user.rb

中的

has_many :jobs
job.rb

中的

belongs_to :user

然后将user_id列添加到Job表格,并在强参数中添加user_id

user_id表中添加Job列:

rails g migration AddUseridToJob user_id:integer
rake db:migrate

在您的模板中: jobs / _form.html.haml 分配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操作链接。
  • 如果您尝试检查现有作业(旧作业),则可能会收到错误,因为现有作业的数据可能不包含user_id
  • 这只会隐藏编辑链接。
  • 您可以使用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

答案 1 :(得分:3)

我建议使用cancancan gem并定义您的能力,如下所示:

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

答案 2 :(得分:1)

您可以创建辅助方法:

@

然后在你的行动之前调用它:

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

答案 3 :(得分:0)

你可能想要这样的东西吗?

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

请注意,owner_id是我编写的。您没有提供有关用户可以/不能编辑的内容的足够上下文。如何确定作业是属于用户还是可由他们编辑。那应该会给你一些东西。

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