用户的Rails模型结构

我是rails的新手,我正在开发第二个rails应用程序。

该应用程序将为用户提供不同的角色,但某些用户将拥有多个角色。

该网站的每个用户都是艺术家。 一些用户将扮演主持人的角色。

我该如何构建这个? 在我使用的一些PHP应用程序中,只有一个用户,然后是is_admin的数据库列等。但是我已经查看了rails应用程序的源代码,并且已经看到了用户和管理员等的单独模型,尽管我我不确定为什么。

那么,我应该有一个带有角色属性的用户模型,可以是主持人,然后在我的视图,路线等中调用用户“艺术家”吗?

或者我应该有一个用户模型,一个inheritance自它的主持人模型,以及一个属于用户的艺术家模型?

我真的很困惑。

你可以寻找gemDevise和CanCan。 这对真是强大的组合。 这使得两个模型User和Role。 在角色中,您可以创建新角色,而无需为其创建新模型。 虽然它创建了模型能力,但您可以在此处定义角色的访问规则。

手册: http : //www.tonyamoyal.com/2010/07/28/rails-authentication-with-devise-and-cancan-customizing-devise-controllers/

在这里你可以找到Devise和CanCan的来源和wikies:

https://github.com/plataformatec/devise

https://github.com/ryanb/cancan

我的模型看起来像这样:

Role.rb

class Role < ActiveRecord::Base has_and_belongs_to_many :users end 

User.rb

 class User < ActiveRecord::Base has_many :accounts has_and_belongs_to_many :roles # Include default devise modules. Others available are: # :token_authenticatable, :confirmable, :lockable and :timeoutable devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable # Setup accessible (or protected) attributes for your model attr_accessible :email, :username, :password, :password_confirmation, :remember_me, :role_ids def role?(role) return !!self.roles.find_by_name(role.to_s.camelize) end end 

Ability.rb

 class Ability include CanCan::Ability def initialize(user) user ||= User.new # guest user if user.role? :administrator can :manage, :all elsif user.role? :operator can :read, Account can :read, Server elsif user.role? :customer can :manage, Account can :read, Server end end end 

在控制器中,您必须只添加以下两行:

 class YourController < ApplicationController before_filter :authenticate_user! load_and_authorize_resource ... end 

如果您需要具有特定于角色的代码或者诸如管理员或主持人之类的代码,则另一个解决方案是创建所有其他类inheritance的基本用户模型。 然后,您可以创建从User模型inheritance的Admin类和Moderator类。 这意味着您可以避免不断检查代码中的用户角色,例如current_user.do_some_admin_thing if current_user.is_admin? 。 你的课程看起来像这样

 class User < ActiveRecord::Base # base user methods in here end class Moderator < User def do_moderator_thing # perform a moderator task end end class Admin < Moderator def do_admin_thing # perform an admin task end end 

在这种情况下,User类具有最基本的权限,主持人可以做所有用户可以加上主持人特定的方法,管理员可以做所有用户和主持人可以加上管理员特定的方法。

所有不同的用户角色都将在数据库中使用相同的表,但您的关注点被巧妙地分成了类,这样可以通过代码检查用户始终处于什么角色来避免过多的条件。

创建新用户也很简单Admin.new :name => 'bob'类然后负责管理用户如何定义为管理员,它提供了一个很好的界面,你不需要知道它的内部工作原理。角色系统与用户互动。

我认为您不必创建不同的模型,因为每个模型都没有特定的字段。 所以你只需要设置每个用户的“角色”。 两个选项:在表User中创建角色表或添加角色字段。 两种解决方案都有效,第二种解决方案更灵活但不太优化。

但是,在您的特定情况下,您没有复杂的角色管理,因此您可以找到更简单的解决方案。 如果您的所有用户都是艺术家,则不必在代码中指定它,它包含在用户内容的隐式描述中。 所以如果用户是管理员,你只需要保存,我认为最好的解决方案是创建一个布尔字段“is_admin”。

之后,您必须在受保护的控制器中创建一些before_filter,如下所示:

 before_filter => :authorize, :only => :new, :edit, :create, :update, :destroy def authorize redirect_to :root if not current_user.is_admin? end 

你可以有这样简单的请求:

 @artists = User.all @moderators = User.where(:is_admin => true) 

如果您寻找更完整的授权系统,您可以查看这个小gem: https : //github.com/ryanb/cancan

但我认为目前情况并非如此。 如果你有一个简单的问题,寻找一个简单的解决方案!

虽然我同意Devise和CanCan的结合是强大而有效的。 让我们以不同的视角来看待它,并牢记协会和代表团。

关联:在面向对象的编程中,关联定义了对象类之间的关系,允许一个对象实例使另一个对象实例代表它执行操作。

委托:委派允许根据另一个对象的行为来定义对象的行为。 “授权”一词是指责任的下放。 委托的主要重点是消息传递,其中对象可以将其无法处理的消息的责任委托给可能(其委托)的对象。

有了这个,如果我们像这样设计我们的用户和角色怎么办? 没有Role类,用户不会inheritance或专门化特定的类(Artist,Admin),所有(Role)类都包含User对象和委托。 我正在思考的方式和使用Rails实现的方式是这样的:

 class User < AR::Base def user_method end end class Artist < AR::Base has_one :user def artist_method # perform an admin task end end class Admin < AR::Base has_one :user def admin_method # perform an admin task end end 

FrancisG.Mossé在他的关于建模角色的文章中描述了这个角色类模型 。

这是我使用的声明性授权 gem的基本设置。 但是如果您的授权要求不仅仅是询问用户的角色类型,那么您可以在没有gem的情况下使用它。

它确实需要一个roles表等等,所以这可能不是你想象的。

 class Role < ActiveRecord::Base belongs_to :user end class User < ActiveRecord::Base has_many :roles def role_symbols roles.map { |r| r.title.to_sym } end def admin? has_role?(:admin) end # include more role booleans or write some ruby magic to be DRY # ... def has_role?(r) role_symbols.include?(r.to_sym) end end # give or take user = User.new user.roles << Role.new :title => "admin" user.roles << Role.new :title => "artist" user.role_symbols # => [:admin, :artist] user.admin? # => true user.has_role?(:artist) # => true 

您可以拥有两个模型User和Role。 角色属于用户。

在Role model中指定用户的角色(如admin,moderator)。