Rails 4,Rolify和Assigning Roles

时间:2015-12-12 22:30:54

标签: ruby-on-rails devise simple-form rolify

我正在尝试使用Rails 4创建一个应用程序。我使用,Devise,Rolify和Simple Form。

我目前的问题是尝试将rolify角色分配给用户。

我有以下代码:

User.rb

def self.find_for_oauth(auth, signed_in_resource = nil)
    # Get the identity and user if they exist
    identity = Identity.find_for_oauth(auth)

    # If a signed_in_resource is provided it always overrides the existing user
    # to prevent the identity being locked with accidentally created accounts.
    # Note that this may leave zombie accounts (with no associated identity) which
    # can be cleaned up at a later date.
    user = signed_in_resource ? signed_in_resource : identity.user

    # p '11111'

    # Create the user if needed
    if user.nil?
      # p 22222
      # Get the existing user by email if the provider gives us a verified email.
      # If no verified email was provided we assign a temporary email and ask the
      # user to verify it on the next step via UsersController.finish_signup
      email_is_verified = auth.info.email && (auth.info.verified || auth.info.verified_email)
      email = auth.info.email
      user = User.where(:email => email).first if email

      # Create the user if it's a new registration
      if user.nil?
        # p 33333
        user = User.new(
          # at least one problem with this is that each provider uses different terms to desribe first name/last name/email. See notes on linkedin above
          first_name: auth.info.first_name,
          last_name: auth.info.last_name,
          email: email,
          #username: auth.info.nickname || auth.uid,
          password: Devise.friendly_token[0,20])
# 
        # debugger

        # if email_is_verified
        #   user.skip_confirmation!
        # end
        user.skip_confirmation! 

        user.save!
      end
    end

    # Associate the identity with the user if needed
    if identity.user != user
      identity.user = user
      identity.save!
    end
    user
  end

  def email_verified?
    self.email && TEMP_EMAIL_REGEX =~ self.email
  end



    def full_name
        [*first_name.capitalize, last_name.capitalize].join(" ")
    end

after_create :add_default_role


  def add_default_role
    add_role(:pending) if self.roles.blank?
  end

Role.rb

class Role < ActiveRecord::Base
  has_and_belongs_to_many :users, :join_table => :users_roles
  belongs_to :resource, :polymorphic => true

  validates :resource_type,
            :inclusion => { :in => Rolify.resource_types },
            :allow_nil => true

  scopify
end

用户/ omniauth_callbacks_controller

def self.provides_callback_for(provider)
    class_eval %Q{
      def #{provider}
        @user = User.find_for_oauth(env["omniauth.auth"])

        if @user.persisted?
           sign_in_and_redirect @user,  event: :authentication

          set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
        else
          session["devise.#{provider}_data"] = env["omniauth.auth"]
          redirect_to new_user_registration_url
        end
      end
    }
  end

          # sign_in_and_redirect_user(:user, event: :authentication)


  [:twitter, :facebook, :linkedin, :google_oauth2].each do |provider|
    provides_callback_for provider
  end

  def after_sign_in_path_for(resource)
    if resource.email_verified?
      super resource
    else
      finish_signup_path(resource)
    end
  end 

用户控制器

private
    def set_user
      @user = User.find(params[:id])
    end

    def user_params
      accessible = [ :first_name, :last_name, :email, {role_ids: []}] # extend with your own params
      accessible << [ :password, :password_confirmation ] unless params[:user][:password].blank?
      accessible << [:approved] if user.admin
      params.require(:user).permit(accessible)
    end

用户#索引

<% Users.each do |user| %>
      <div class="row">
            <div class="col-xs-5">
                <%= link_to "#{user.full_name}", user %>
            </div>
            <div class="col-xs-5">
                <%= link_to "#{user.email}", user %>
            </div>
            <div class="col-xs-2">
                 <%= link_to "edit", edit_user_path(user) %>
            </div>
    </div> 
    <% end %> 

用户#形式

<%= simple_form_for(@user) do |f| %>
            <%= f.error_notification %>
              <% Role.all.each do |role| %>
              <div class="form-inputs">

              <%= f.input "user[role_ids][]", role.id, collection: @user.role_ids.include?(role.id) %>
              <%= role.name %>

              </div>

              <div class="form-actions">
                <%= f.button :submit, "Add role", :class => 'formsubmit' %>
              </div>

我也尝试过:

<%= f.association :roles %>
<%= role.name %>
用户#表单中的

迁移以将角色添加到角色表:

class AddRolesToRolifyTable < ActiveRecord::Migration
  def change

    ['admin', # internal  admin
     'manager', # internal  manager
     'editor', # internal  web content editor
     'support', # internal  user support
     'educator', # lecturers
     'faculty_manager', #manage the business side 
     'project_manager', 
     'pending', # new people that are not yet confirmed in a role - default role assignment

     ].each do |role_name|
      Role.create! name: role_name
  end

  end
end

当我保存并尝试运行本地主机并转到用户#index时,我收到一条错误消息:

 Couldn't find User with 'id'=

突出显示此方法:

 private
    def set_user
      @user = User.find(params[:id])
    end

我不能说我已正确理解rolify如何与设计一起使用。我的控制台显示我在db中有两个测试用户,每个用户都有一个id(所以我不知道如何进一步探索这个错误)。有没有人知道我哪里出错了?

我已使用这篇文章中的建议调整了此设置:

Defining Roles with Rolify

1 个答案:

答案 0 :(得分:1)

Rolify and Devise

  

我不能说我已正确理解rolify如何与设计一起使用。

Rolify and Devise完成了截然不同的工作。两者之间没有实际的整合。

Devise是一种身份验证解决方案,身份验证只是确定是否有签名用户以及该用户是否是他/她声称的用户。

另一方面,

授权是关于允许谁在系统中执行操作的人。 Rolify是一个通用角色库,旨在用作身份验证解决方案的一小部分。只需使用.has_role?定义您的授权就会变得非常混乱。

通常与CanCanCanPundit相结合,提供定义身份验证规则的工具。

收集助手

Rails的关联built in helpers for creating selects and checkboxessimple_form更进一步。

因此,假设您有users/:user_id/edit路由,其中​​管理员可以编辑用户个人资料并添加角色:

<%= simple_form_for(@user) do |f| %>
  <fieldset>
    <legend>Roles</legend>
    <%= f.association :roles, as: :check_boxes, collection: Role.all %>
  </fieldset>
  <% f.submit %>
<% end %>

请注意,在这种情况下,您不需要特殊的表单来编辑角色 - 这在创建和编辑用户时都有效。

你的params卫生设施有点偏差:

def user_params
  accessible = [ :first_name, :last_name, :email, role_ids: []]
  accessible << [ :password, :password_confirmation ] unless params[:user][:password].blank?
  accessible << [:approved] if user.admin? # don't do this. There are better ways.
  params.require(:user).permit(accessible)
end

此外:

Migrations are for altering the database schema, not for seeding the system with default info.请使用rake db:seeds或创建自己的佣金任务。

我还会质疑你是否真的需要一个待定角色和approved参数。我只是检查用户是否没有角色 - 哪个事实意味着他正在等待。当管理员或对等方验证用户时,您将添加approved角色。