用户的属性取决于用户的类型:在Rails中实现的最佳方法 [英] User's attributes depend on user's type: best way to implement in Rails

查看:100
本文介绍了用户的属性取决于用户的类型:在Rails中实现的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有基本信息和特定于活动的信息的用户. 假设用户是一名足球运动员,其个人资料如下所示:

I have a user with basic infos and activity specific infos. Let's say User is a Footballer, its profile will look like :

User.rb #common infos
  firstname
  lastname
  email
  sex
  address_id

Footballer.rb #or something accurate
  position
  team
  age
  weight
  shoe_size
  ...

但是,如果用户为Boxer,则其个人资料将由以下内容组成:

However, if the user is as Boxer, its profile will be composed of :

#User.rb #same as footballer
  firstname
  lastname
  email
  sex
  address_id
  avatar

#Boxer.rb
  weight
  handicap
  league
  ...

将这种逻辑集成到rails中的最佳方法是什么? 配置文件将在users#show.html中呈现 我的应用易于注册(仅电子邮件),并且团队由多个配置文件组成,因此反转逻辑(通过创建Footballer has_one :basic_infosBoxer has_one :basic_infos)似乎很复杂,这需要在每个模型上调用以获取基本信息突出显示(例如全名和头像)

What would be the best way to integrate this logic in rails? The profile would be rendered in users#show.html My app has easy registration (only email) and teams composed of multiple profiles, so it seems complicated to invert the logic (by creating a Footballer has_one :basic_infos and Boxer has_one :basic_infos), that would require a call on each model for basic infos highlight (such as complete name and avatar)

我对此一无所知,因此非常欢迎您提供任何帮助

I'm stucked on this, so any help would be very welcome

推荐答案

我在这里看到以下选项.

I see the following options here.

1.单表继承( STI )

1. Single table inheritance (STI)

只需将所有字段转储到一个表中,然后将其设为class Boxer < Userclass Footballer < User.

Just dump all the fields in one table, and make class Boxer < User, class Footballer < User.

优点:实施简单.

缺点:表变得肿.字段是共享的,即您的足球运动员将拥有weight和其他字段,反之亦然.

Cons: Table become bloated. Fields are shared, i.e. your footballer will have weight and other fields and vice versa.

2.将基本信息移到另一个表

这就是您已经概述的选项.

That's the option you already outlined.

优点:清理表,适当分隔字段.

Pros: Clean tables, proper separation of fields.

缺点:复杂的实现.您将必须确保每个实例始终只有一个基本配置文件.因此,您将必须注意关联宏的:delete_all/:destroy_all选项,也许也要注意before_create/after_destroy.

Cons: Complex implementation. You will have to ensure that there is always one and only one basic profile for each instance. So you will have to pay attention to :delete_all/:destroy_all options of association macroses, and maybe before_create/after_destroy as well.

以下是有关如何在您的代码中进行组织的示例:

Here is an example on how to organize that in your code:

# models

class Profile < ActiveRecord::Base
  # you need to create
  #   t.integer :user_id
  #   t.string  :user_type
  # in a migration for 'profiles' table

  belongs_to :user, polymorphic: true
end

class User < ActiveRecord::Base
  # This will disable STI
  self.abstract_class = true
  has_one :profile, as: :user, dependent: :destroy

  def some_common_user_method
    # ...
  end

  def pick_profile
    self.profile && return self.profile
    if self.persisted?
      self.create_profile
    else
      self.build_profile
    end
  end
end

class Footballer < User
end

# controllers

class UsersController < ApplicationController
  before_action :set_klass
  before_action :set_user, except: [:index, :create]

  # ...

  def create
    @user = @klass.new
    @user.pick_profile
    # etc...
  end

  def destroy
    @user.destroy
  end

  private

  def set_klass
    # white-list search for class
    @klass = User.descendants.find{|k| k == params[:type].camelize.constantize}
  end

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

# routes

# for URLs like /users/1?type=footballer
resources :users

# for URLs like /users/footballer/1
resources :users, path_prefix: '/users/:type'

3.添加序列化字段

3. Adding a serialized field

只需添加具有特定运动员详细信息的JSON/YAML的details字段,并将公共字段作为单独的数据库字段即可.

Just add details field with JSON/YAML of specific sportsmen details, and have common fields as separate DB fields.

优点:实施简单.数据库结构也保持简单.

Pros: Simplicity of implementation. Database structure stays simple as well.

缺点:您将无法在特定运动员的字段上进行有效的查询,即您将需要获取每条记录以了解其详细信息.

Cons: You won't be able to make effective queries on specific sportsman's fields, i.e. you will need to fetch each record to know its details.

4.使用特定于Postgresql的序列化列

4. Using Postgresql-specific serialized columns

与上述相同,仅不包含缺点"部分.您将能够对序列化数据进行有效的查询.

Same as above, only without "cons" part. You will be able to make efficient queries on serialized data.

缺点:您将需要学习如何使用该字段并进行查询.使用MySQL无法实现.

Cons: You will need to learn how to use that fields and query them. Not possible with MySQL.

这篇关于用户的属性取决于用户的类型:在Rails中实现的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆