允许用户创建和管理其他用户

时间:2013-06-01 20:21:06

标签: ruby-on-rails database-design activerecord

我有一个用户模型,名为帐户 {ID,姓名,地址,电子邮件,密码等...},我希望能够允许该用户创建和管理其他用户用户。我创建了一个 Relationships 模型,{manager_id,care_id,relationship等...}来跟踪用户和其他托管用户之间的关系。基本上,用户has_many relationships through: :relationships, source: "care_id"。据我所知,在建立关系之前,必须首先创建一个新用户,以获得新的用户ID。普通用户在注册时需要验证电子邮件,密码等...但是,对于托管用户,您只需要一个名称,他们可以在以后编辑其他所有内容。

实现此类功能的最佳/正确方法是什么。我需要一个新的控制器吗?或者,我可以将新操作添加到默认用户控制器吗?如何在没有用户模型的正常验证的情况下创建新用户(名称,电子邮件,密码不能为空,必须具有一定的长度等等)。如何使用正确的用户ID自动创建关系。在此先感谢您的帮助和/或指出我正确的方向。

这个想法是这样的:用户可以注册并管理他的帐户。然后,他可以创建一个“关心”帐户,基本上只需要一个名称即可开始,并且不需要其他验证,因为子帐户不会使用电子邮件/密码登录。如果子帐户以后想要访问,则父帐户可以为其设置电子邮件/密码,它将成为完整帐户。此父帐户经理还可以邀请另一个帐户(可能是配偶)充当此子帐户的另一个经理。

更新:更多信息:

帐户模型

class Account < ActiveRecord::Base

validates :email, presence: true, 
                format:     { with: VALID_EMAIL_REGEX},
                uniqueness: { case_sensitive: false },
                length:     { maximum: 32 },
                unless: :child?

has_many :relationships, foreign_key: "manager_id", dependent: :destroy
has_many :cares, through: :relationships, source: :care
has_many :reverse_relationships, foreign_key: "care_id", class_name: "Relationship", dependent: :destroy
has_many :managers, through: :reverse_relationships, source: :manager
...
def child?
  false
end

class CareUser < Account

 def child?
   true
 end
end

关系模型

class Relationship < ActiveRecord::Base
 attr_accessible :care_id, :manager_id, :type

 belongs_to :manager, class_name: "Account"
 belongs_to :care, class_name: "Account"

 validates :manager_id, presence: true
 validates :care_id, presence: true
end

Cares Controller

class CaresController < ApplicationController
  def index
     @cares = current_user.cares
  end

  def new
    @user = CareUser.new
    @care = Relationship.new
  end

  def create
    @user = CareUser.new(params[:first_name])
    logger.info @user.inspect
    if @user.save(false)
      @care = current_user.relationships.build(current_user.id, @user.id, params[:relation])
      if @care.save
        flash[:success] = "New care has been successfully added."
      else
        flash[:error] = "Failed"
        render action: new
      end
    else
      flash[:error] = "Failed adding user"
      render action: new
    end

  end

  def show
  end

  def edit
  end

  def update
  end

  def destroy
  end
end

@user = CareUser.new得到uninitialized constant CaresController::CareUser时,子类......但是如果将其设置为父类的@user = Account.new,则不会显示错误。

提交表单,cares / new.html.erb

不确定设置表单的正确方法,但自提交到两个模型后,我使用的是form_tag而不是form_for。目前我似乎无法正确提交表单,不确定问题是否在表单,模型或控制器中。

<div class="row">
  <div class="span6 offset3">
    <h1>New care</h1>
    <%=  form_tag("/cares", method: :post) do %>
        <% if @user.errors.any? %>
            <div id="error_explanation">
              <div class="alert alert-error">
                The form contains <%= pluralize(@user.errors.count, "errors") %>
              </div>
              <ul>
                <% @user.errors.full_messages.each do |message| %>
                    <li><%= message %></li>
                <% end %>
              </ul>
            </div>
        <% end %>
        <% if @care.errors.any? %>
            <div id="error_explanation">
              <div class="alert alert-error">
                The form contains <%= pluralize(@care.errors.count, "errors") %>
              </div>
              <ul>
                <% @care.errors.full_messages.each do |message| %>
                    <li><%= message %></li>
                <% end %>
              </ul>
            </div>
        <% end %>

        <%= label_tag(:first_name, "First name:") %>
        <%= text_field_tag(:first_name) %>

        <%= label_tag(:relation, "Relationship") %>
        <%= select_tag(:relation, options_for_select([ ["Son", "1"], ["Daughter", "2"], ["Father", "3"], ["Mother", "4"], ["Grandson", "5"], ["Granddaughter", "6"], ["Grandfather", "7"], ["Grandmother", "8"] ])) %>


        <br>
        <%= submit_tag("Create care account") %>


    <% end %>
  </div>

</div> 

2 个答案:

答案 0 :(得分:0)

根据您的要求,

I have a user model {id, name, address, email, password, etc ... }, and I want to be able to allow that user to create and manage other users. 

如果您只想跟踪用户的经理是谁,解决方案是在用户表格中包含“ manager_id ”列。如果manager_id为NULL,则用户自己是高级经理,否则相应的经理ID。

如果您需要存储关系的更多详细信息,则需要创建分离关联表 user_managers 并说

用户has_many:经理,通过user_mangers。

在这些情况下,您不必始终首先创建用户记录。每当您创建新用户时,我都会假设您为该用户分配了一个管理员(如果需要)。

manager = User.first
user = User.new
user_manager = manager.user_managers.new
user_manager.student = user
user.save!

user_managers表结构:

 id, user_id, student_id

答案 1 :(得分:0)

您可以创建此结构来管理具有无限级别的用户层次结构:

class User < ActiveRecord::Base
  has_many :user_relations, :dependent => :destroy
  has_many :subordinates, :through => :user_relations
  has_many :inverse_user_relations, :class_name => "UserRelation", :foreign_key => "subordinate_id"
  has_many :superiors, :through => :inverse_user_relations, :source => :user
  ...
end

class UserRelation < ActiveRecord::Base
  belongs_to :user
  belongs_to :subordinate, :class_name => "User"
end

manager.subordinates = [subordinate_one, subordinate_two]
subordinate_one.superiors #manager user
manager.subordinates.size #2 users
admin.subordinates << manager
manager.superiors #admin user
admin.subordinates.size #1 user

然后,要管理用户权限和验证,您可以使用组合 cancan gem和用户层次结构,用于执行与每种用户类型相关的验证。

class User < ActiveRecord::Base
  validates :user_name, :presence => true, :uniqueness => true
  #and other common validations
end

class Subordinate < User
  #specific validations for this user type
end

class OtherUser < User
  #specific validations for this user type
end

然后在UsersController中,您可以创建类似这样的内容:

def create
  @user = Subordinate.new(params[:user])
  @user.save
end

def create
  @user = OtherType.new(params[:user])
  @user.save
end