2010-11-03 25 views
1

我在我的應用程序中有一個權限模型,它將(用戶,角色,項目)聯繫在一起。Rails3 - 權限模型Before_Save檢查?

我正在尋找學習如何做的是防止用戶去除親自爲他們的項目...

你能給我以下的反饋?

class Permission < ActiveRecord::Base 
. 
. 
. 
    #admin_lock makes sure the user who created the project, is always the admin 
    before_save :admin_lock 

    def before_save 
    #Get the Project Object 
    project = Find(self.project_id) 
    if project.creator_id == current_user.id 
     # SOME HOW ABORT OR SEND BACK Not Allowed? 
    else 
     #continue, do nothing 
    end 
    end 

end 

這看起來是不是正確的做法?

而且,我不知道該怎麼做上面以下兩件事情:

  • 如何中止防止保存,併發送回一個錯誤味精?
  • 獲取模型中的設計,current_user.id,這似乎不可能,那麼Rails的大師應該如何做類似上述的東西?

感謝您在

回答

2

閱讀如何中止防止保存,併發送回一個錯誤味精?

回調鏈中返回虛假告訴activemodel的停止(類似於如何驗證過程中添加錯誤的模型告訴它停止在該點)

self.errors.add_to_base「味精」將增加對模型的錯誤,然後可以在視圖上呈現。

在模型中獲取devise,current_user.id,這似乎不可能,那麼Rails的上級如何做類似上面的東西?

模型不應該真正瞭解像當前請求這樣的事情,如果可能的話,您應該將事情鎖定在控制器/操作級別。

編輯:

所以,控制器的作用是處理涉及聚聚基於請求正確的信息的一切,並將它傳遞給視圖(成爲響應)。人們經常說「讓你的模型變胖,你的控制器很瘦」,但是可以說任何包含面向對象設計的系統都可以這麼說 - 你的邏輯應該儘可能地放在對象中。

也就是說,控制器的重點在於處理將正確的事情路由到正確的位置,而身份驗證絕對是路由問題。

您可以輕鬆地將比較creator_id的行與操作中的用戶標識進行比較,並根據該標識作出反應。

現在,有時候你真的需要模型中的東西,而且沒有辦法繞過它。這成爲一個問題,因爲你需要打鐵路才能到達那裏。一種方法是在模型上attr_accessor current_user字段,並在初始化時傳遞它。另一種方法是從params散列中刪除用戶不允許在動作中更改的字段。儘管如此,它們都不是那麼好。

+0

馬特 - 謝謝。所以如果Models不知道current_user。我如何在控制器級別執行此操作。在控制器的某處,我做了一些類似admin_lock(current_user)的事情? admin_lock在哪裏居住,在控制器或模型中?我有點困惑,因爲我認爲模型應該做所有這些類型或許可/驗證的東西,而控制器是真正的光?幫幫我? – AnApprentice 2010-11-03 00:50:07

+0

編輯我的答案,對不起,我沒有更好的爲你:) – 2010-11-03 01:09:39

1

與Matt一致,你應該嘗試使用控制器進行重定向。該模型應該具有確定重定向是否合適的邏輯。也許類似

class ProjectsController < ApplicationController 
    def update 
    redirect_to(projects_url, :alert => "You can't remove yourself from this project.") and return if Role.unauthorized_action?(:update, params[:project]) 
    @project = Project.find(params[:id]) 
    if @project.update_attributes(params[:project]) 
    ... 
    end 

class Role 
    def self.unauthorized_action?(action, params) 
    # your logic here 
    end 

你應該檢查出CanCan的一些想法。

0
  1. 在權限模型採取一個字段project_creater布爾
  2. 在項目模型
    before_create :set_project_ownership 
        def set_project_ownership 
        self.permissions.build(user_id: User.current.id, project_creater: true) 
        end
  3. 在項目控制器
    before_filter :set_current_user
  4. 在應用控制器
    def set_current_user 
        User.current = current_user 
    end