2014-10-19 55 views
1

在我的應用程序中,我有以下資源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 

但我不知道如何安全的,這是。似乎用戶可以訪問其他用戶的帖子。

這是正確的嗎?我怎麼能這樣做?

回答

1

我的做法是對內存使用自定義的驗證與「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的檢驗邏輯,應該是OK:

if @post.user == current_user or @post.user.blank? 

但是,如果你擔心這個邏輯的全面性,讓我們寫測試或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 
1

我不喜歡這樣,因爲這將是(以服務對象或可能)更好的邏輯是在模型:

用戶必須有兩種類型 一個。登錄 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 

你也可能要由Ryan貝茨或因爲它已停滯,您可以使用cancacnan一段時間來嘗試cancan寶石..

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 
相關問題