6

Tôi có một ứng dụng đường ray với một mô hình người dùng, có khả năng có nhiều vai trò. Tôi thực hiện điều này bằng cách sử dụng bitmask như thế này:Cho phép chỉ có một số giá trị có thể trong Rails thông số mạnh

class User < ActiveRecord::Base 
    DEFAULT_ROLES = %w[developer entrepreneur] 
    ROLES = ['admin', 'entrepreneur', 'developer'] 

    def has_role?(role) 
    roles.include?(role.to_s) 
    end 

    def is?(role) 
    has_role?(role) 
    end 

    def roles=(roles) 
    self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) 
    end 

    def roles 
    ROLES.reject do |r| 
     ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero? 
    end 
    end 
end 

Trong trang đăng ký cho các ứng dụng, tôi muốn người dùng lựa chọn nếu họ là một 'doanh nhân' hoặc 'phát triển'. Tuy nhiên, tôi muốn đảm bảo rằng họ không thể tự gán cho mình (hoặc bất kỳ ai khác) bất kỳ vai trò nào khác, trừ khi họ đã là quản trị viên.

Suy nghĩ đầu tiên của tôi là để làm điều này trong phương pháp roles= bởi changin nó trông giống như

def roles=(roles) 
    unless current_user.is?(:admin) 
     validates_inclusion_of roles, :in => DEFAULT_ROLES 
    end 
    self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) 
    end 

Tuy nhiên, khi tôi phát hiện ra, bạn không thể truy cập current_user từ bên trong một mô hình (mà tôi đoán làm cho nếu bạn nghĩ về nó ...)

Nỗ lực tiếp theo của tôi là xem tôi có thể làm điều này bằng cách sử dụng Strong Parameters hay không.

tôi đã mong đợi nó sẽ giống như thế này (tôi đang sử dụng đưa ra, trọng các RegistrationsController)

class RegistrationsController < Devise::RegistrationsController 

    private 
    def sign_up_params 
    if (user_signed_in?) && (current_user.is?(:admin)) 
     params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, {roles: User::ROLES}) 
    else 
     params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, {roles: User::DEFAULT_ROLES}) 
    end 
    end 

    def account_update_params 
    if (user_signed_in?) && (current_user.is?(:admin)) 
     params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, :current_password, :about_me, {roles: User::ROLES}) 
    else 
     params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, :current_password) 
    end 
    end 
end 

Tuy nhiên, khi tôi đã cố gắng đó, tôi nhận điều này: enter image description here mà làm cho tôi nghĩ rằng tôi m hiểu lầm các tham số mạnh mẽ thực sự hoạt động như thế nào.

Có thể hạn chế những giá trị người dùng có thể nhập cho bất kỳ lĩnh vực nhất định trên cơ sở đó vai trò người dùng với thông số mạnh mẽ? Nếu không, có cách nào khác để thực hiện việc này không?

+0

Nó phải được xác định là xác thực mô hình. Tham số mạnh là để lọc các khóa param, không phải các giá trị. – kengo

+0

@kengo - Làm cách nào để xác thực trong mô hình nếu tôi không thể truy cập vai trò người dùng hiện tại? (vì quản trị viên có thể đang sửa đổi người dùng khác, không chỉ là bản thân họ) – Ephraim

+0

Bạn không thể xác định tham số mạnh mẽ như before_action. Sử dụng như thế này trong phương thức tạo hoặc cập nhật. Account.new (account_update_params) – kengo

Trả lời

6

I figured it out, dưới đây là cách tôi đã làm nó. (Đây là phương pháp ghi đè lập mưu của RegistrationController, nếu bạn không sử dụng đưa ra, sau đó chỉ cần thay thế bất cứ phương pháp kiểm soát những gì các thông số được nhập vào một người dùng mới.)

class RegistrationsController < Devise::RegistrationsController 

private 
    def sign_up_params 
    parameters = params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, :about_me, roles: []) 
    unless (user_signed_in?) && (current_user.is?(:admin)) 
     parameters[:roles] = parameters[:roles].reject { |h| !User::DEFAULT_ROLES.include? h } 
     parameters 
    end 
    end 


    def account_update_params 
    if can? :assign_roles, :all 
     params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, :current_password, :about_me, roles: []) 
    else 
     params.require(:user).permit(:name, :school, :email, :password, :password_confirmation, :current_password) 
    end 
    end 

end 

tôi chỉ lọc ra các tham số trong các thông số [: vai trò] để chỉ bao gồm các giá trị được chứa trong User::DEFAULT_ROLES (được hiển thị ở trên trong câu hỏi) và sau đó trả lại đối tượng parameters.

+0

Yup, params là sửa đổi (bạn đã nhận nó được sắp xếp trước khi tôi có thể lấy lại cho bạn) . – railsdog

Các vấn đề liên quan