在我的应用程序中,我有以下资源Post和User。我希望用户能够更新自己的帖子和访客帖子,我希望访客能够更新其他访客帖子,但不能更新用户。访客只是非用户(@post.user.blank
)。
Post Model
belongs_to :user
# columns: user_id, name, body
end
User Model
has_many :posts
end
我的控制器让我感到困惑,因为我不确定如何制作它所以更新帖子可以由当前用户或访客完成,而不允许每个人都更新任何帖子。主要是另一个用户更新另一个用户帖子。
def update
@post = Post.find(params[:id])
if @post.update(post_params)
redirect_to @post
else
render action: 'edit'
end
end
def post_params
params.require(:post).permit(:name, :body)
end
我在考虑做:
def update
@post = Post.find(params[:id])
if @post.user == current_user or @post.user.blank?
if @post.update(post_params)
redirect_to @post
else
render action: 'edit'
end
end
end
但我不确定这是多么安全。似乎用户可以访问其他用户帖子。
这是对的吗?我怎么能这样做?
答案 0 :(得分:1)
我会这样做,因为逻辑更适合在模型中(或者可能在服务对象中):
用户必须有两种类型 一个。登录 湾客
class Post < AR::Base
...
...
def created_by_guest?
self.user == nil #probably created by guest if user is nil
end
def update_by_user(user, attributes)
return false if user.guest and self.created_by_guest?
#add code to try updating return true if it worked and false if did not work
end
end
控制器中的
def update
@post = Post.find(params[:id])
if @post.update_by_user(current_user, update_params)
#redirect to show
else
#edit page
end
end
你也可以尝试一下Ryan bates的cancan gem,或者因为它已经停滞了一段时间你可以使用cancacnan ..
答案 1 :(得分:1)
如果满足以下条件之一,您希望允许更新:
让我们在模型中创建一个方法来检查是否允许用户根据传递以下两个条件之一进行更新:
Post Model
belongs_to :user
# columns: user_id, name, body
def updatable_by?(user)
@user_id.nil? || user == self.user # return true for guest post OR post owner
end
end
然后,更新等待检查结果:
def update
@post = Post.find(params[:id])
if @post.updatable_by?(current_user) # <-- update if current_user is allowed
if @post.update(post_params)
redirect_to @post
else
render action: 'edit'
end
end
end
答案 2 :(得分:1)
我的方法是使用&#39; update_user&#39;内存的附加属性如下:
class Post < ActiveRecord::Base
belongs_to :user
attr_accessor :update_user
validate :validate_user_scope, on: :update
private
def validate_user_scope
if !(user.blank? || user == update_user)
errors.add(:update_user, :not_permitted)
end
end
end
class User < ActiveRecord::Base
has_many :posts
end
当然,这个优点是检查逻辑是在模型级别(而不是控制器)的Rails验证下完成的。
用户的访问范围(或访问权限)应该是&#34;业务逻辑&#34;和&#34;业务逻辑&#34;应该是模型逻辑之一,以便在模型级别编写,我认为。
我认为用户2784630在以下片段中的检查逻辑应该没问题:
if @post.user == current_user or @post.user.blank?
但是,如果你担心这个逻辑的全面性,那就让我们写一下test或rspec。以下是带有灯具的test / models / post_test.rb示例:
require 'test_helper'
class PostTest < ActiveSupport::TestCase
...
# test all of posts of guest, user-A, and user-B are updated by
# guest, user-A, and user-B
test "update guest post by user_A" do
p = posts(:guest_post)
p.update_user = users(:user_A)
assert p.valid?
end
...
end