在Devise中创建属于另一个用户的用户?

时间:2011-12-13 07:59:08

标签: ruby-on-rails devise

我正在尝试创建一个包含2个用户级别的简单博客应用程序:“writer”和“manager”

作家属于经理,经理可以有很多作家。

作家只能看到他们自己的帖子,但经理可以看到他们作家的所有帖子。

现在我的问题是,我应该如何实现这种类型的系统?

我很确定我应该使用Devise来生成用户身份验证。但是,我应该为每种类型的用户(作者或模型)生成单独的模型,还是应该生成角色表?

我不知道这是否足够具体;我花了一天时间在这上面没有任何解决方案,所以如果你需要了解更多,请告诉我,我会在评论中回答。提前致谢

4 个答案:

答案 0 :(得分:7)

听起来像是一个带有manager_id的简单用户表。

create_table :users do |t|
  # ...other columns...

  t.integer :manager_id
end

class User < ActiveRecord::Base
  # Returns all writers under this manager
  has_many :writers, :class_name => 'User', :foreign_key => :manager_id

  # Returns this writer's manager
  belongs_to :manager, :class_name => 'User'

  # Allows this user to be author of posts
  has_many :posts

  # Associates posts of all writers under this manager
  has_many :writers_posts, :through => :writers, :class_name => 'Post'

  # If user has no manager, she's a manager
  def manager?
    manager_id.nil?
  end

  # If user has a manager, she's a writer
  def writer?
    !manager?
  end
end

这使您可以与用户一起做以下事情。

if @user.manager?
  @user.writers # => [<User>, <User>, ...]
  @user.writers_posts # => [<Post>, <Post>, ...]
end

if @user.writer?
  @user.manager # => <User>
end

此实现仅通过管理员的存在来确定用户是管理员还是作者。如果用户有经理,她必须是作家。不过,她是一名经理。如果这不够灵活,您可以添加额外的布尔列,指定用户是一个,另一个,还是两者。另请注意,这只是一个具有编写器和管理器方法的User模型。所以你可能调用@writer.writers_posts(这不是作为编写者用户),但你不应该。

验证

由于您拥有的是常规User模型,因此您可以按照任何Devise教程为其设置身份验证。作家和经理都只是简单登录的用户。

授权

就权限和帖子可见性而言,这一切都归结为能够在当前用户上调用上述方法。

if current_user.manager?
  current_user.writers_posts.each do |post|
    # display post
  end
end
坦率地说,CanCan是一种矫枉过正的行为。您只需在视图中添加一些before_filter和一些if current_user.manager?条件即可。 CanCan更全面,根据我的经验,它在大多数应用程序中都是太多了。

答案 1 :(得分:1)

看一下以下的宝石:

CanCan for authorization更多信息http://railscasts.com/episodes/192-authorization-with-cancan

对于您的用户模型,您可以使用指定用户角色的列=&gt;经理或编写者,并且对于每个用户,您可以拥有manager_id列(当用户是经理时,您将在此处放置null)

编辑:您也应该使用Devise进行身份验证

答案 2 :(得分:0)

是的,您应该使用设计,并且您应该为有权访问所有帖子的经理实施管理员角色。 https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-role提供了有关如何执行此操作的说明。

答案 3 :(得分:0)

我喜欢hakunin的答案,但我认为他在用户模型中遗漏了一些东西。我认为需要有一个“源”,否则会出现“堆栈级太深”的错误。

# Associates posts of all writers under this manager
has_many :writers_posts, :through => :writers, :class_name => 'Post', :source => :posts