【问题标题】:Sub-Users in Devise on Rails 6Devise on Rails 6 中的子用户
【发布时间】:2019-12-12 06:16:39
【问题描述】:

参考之前提出并回答的问题:sub-users-and-devise OP 询问如何在设计中拥有子用户。给出的答案是在 User 模型中建立belongs_to has_many 关系:

 class User
  belongs_to :parent, :class_name => 'User'
  has_many :children, :class_name => 'User'
  ...
 end

然后修改控制器:

class UsersController < ApplicationController  
  def new
    @user = User.new
    @user.parent_id = params[:parent_id] 
    respond_to do |format|
  end
  end

对于我正在尝试做的事情,这似乎是一个完美的解决方案,但我很难考虑需要进行哪些迁移才能完成这项工作。我正在使用设计,我的模型和用户表已经存在,所以我需要实际生成一个迁移。会像在users 表中添加parent_id 列一样简单吗?使用add_reference 迁移不是更好吗?

我试过了:

class AddUsersToUser < ActiveRecord::Migration[6.0]
  def change
    add_reference :users, :user, foreign_key: true
  end
end

但我得到的是user_id 字段,而不是parent_id 字段,因此任何引用parent_id 的代码(例如视图或助手)都会出错

未定义的方法`parent_id'。

有人可以帮助我了解完成这项工作所需的迁移吗?

或者有没有更好的方法在 Devise 中设置子用户?

如果您需要,这里是我的应用程序中的相关文件:

路线:

Rails.application.routes.draw do

  devise_for  :users, controllers: {
              :registrations => "users/registrations"
  }
...
end

控制器:

class Users::RegistrationsController < Devise::RegistrationsController
  # before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  # GET /resource/sign_up
  def new
    build_resource
    resource.parent_id = params[:parent_id]
    yield resource if block_given?
    respond_with resource
  end
end

型号:

class User < ApplicationRecord
  belongs_to :parent, :class_name => 'User'
  has_many :children, :class_name => 'User', dependent: :destroy

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :lockable, :timeoutable, :trackable
end

产生错误的助手:

module UsersHelper

  # Returns the Gravatar for the given user.
  def gravatar_for(user, options = { size: 50 })
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=40&d=blank"
    image_tag(gravatar_url, class: "gravatar")
  end

  def current_user_is_head_of_household
    current_user.parent_id.nil?
  end

  def current_user_is_member_of_household
    !current_user.parent_id.nil?
  end
end

调用current_user_is_head_of_household的视图:

<h1>Lobby</h1>
<p>This is slated to be the jumping off point (home) where members can access the blog, training, personal information tracker and the various calculators.</p>

<% if current_user_is_head_of_household %>
  <%= link_to "Add user to your household", new_user_registration_path %>
<% end %>

最后抛出的错误:

未定义的方法 `parent_id' 用于# 你的意思是?父母 父母=

    Extracted source (around line #11):

9
10      def current_user_is_head_of_household
11        current_user.parent_id.nil?
12      end
13    
14      def current_user_is_member_of_household

【问题讨论】:

  • 您在模型下发布了控制器代码。在处理递归(或)树结构时,我通常使用美妙的ancestry gem。我认为您还需要将parent_id(它是documented in Devise github)列入白名单
  • 哎呀...是的,我做了后控制器代码而不是模型代码...感谢您发现这一点。我刚刚在帖子中解决了这个问题。也感谢关于祖先宝石的提示!

标签: ruby-on-rails ruby devise


【解决方案1】:

迁移以添加父引用和外键

class AddParentToUser < ActiveRecord::Migration[6.0]
  def change
    add_reference :users, :parent, index: true
    add_foreign_Key :users, :users, column: :parent_id
  end
end

用户模型关联

  belongs_to :parent, :class_name => 'User', optional: true
  has_many :children, :class_name => 'User', foreign_key: :parent_id

【讨论】:

  • 标记为已接受。按照给定的方式对我的模型和迁移进行了更改,它对我有用。现在也看到它帮助我在脑海中解决它。谢谢西坎达!
  • 乐于助人:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 2015-03-03
  • 2013-11-03
相关资源
最近更新 更多