![](/img/trans.png)
[英]How to allow users to delete or update non-user resources and only there own?
[英]How to update a resource as current user or a non-user?
在我的應用程序中,我有以下資源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
但我不確定這是多么安全。 似乎用戶可以訪問其他用戶的帖子。
這是正確的嗎? 我怎么能這樣做?
我會這樣做,因為邏輯在模型中(或者在服務對象中)會更好:
用戶必須有兩種類型a。 登錄的b。 客人
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
另外你可能想嘗試瑞安貝茨的cancan gem,或者因為它已經停滯了一段時間你可以使用cancacnan ..
如果滿足以下條件之一,您希望允許更新:
讓我們在模型中創建一個方法,以檢查是否允許用戶根據傳遞以下兩個條件之一進行更新:
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
我的方法是使用內存上的'update_user'附加屬性進行自定義驗證,如下所示:
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驗證下完成的。
用戶的訪問范圍(或訪問權限)應該是“業務邏輯”之一,“業務邏輯”應該是模型邏輯之一,因此我認為在模型級別編寫會很好。
我認為user2784630在以下片段中的檢查邏輯應該沒問題:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.