【问题标题】:Rails - Polymorphic Association to Create Different ProfilesRails - 创建不同配置文件的多态关联
【发布时间】:2016-03-06 04:07:17
【问题描述】:

尝试使创建用户时,根据他们选择是学生还是公司,rails 将创建该用户学生个人资料或公司个人资料。

我尝试使用多态关联进行设置,但无法弄清楚如何根据视图中选择的内容在模型层生成配置文件。

模型

class User < ActiveRecord::Base

 has_secure_password 

  has_one :student_profile, dependent: :destroy
  has_one :corporate_profile, dependent: :destroy
  has_many :searches, dependent: :destroy


  #attr_accessor :profile_type - removed due to Rails 4, pushed strong params in controller

  before_create :create_profile

      def create_profile
        if profile_type == 1
          build_student_profile
        else
          build_corporate_profile
        end
      end
 end

学生和公司简介

class CorporateProfile < ActiveRecord::Base # or possibly inherit from ActiveRecord::Base if not using inheritance

  belongs_to :user

end

class StudentProfile < ActiveRecord::Base # or possibly inherit from ActiveRecord::Base if not using inheritance

  belongs_to :user

end

查看

这里我有两个单选按钮来决定注册表单上的用户类型

<%= bootstrap_form_for(@user) do |f| %>

            <div class="field">
              <%= f.form_group :gender, label: { text: "Gender" }, help: "Are you a corporate or a student?" do %>
              <p></p>
                  <%= f.radio_button :profileable, 1, label: "Student",   inline: true %>
                  <%= f.radio_button :profileable, 2, label: "Corporate", inline: true %>
                <% end %>
          </div>

用户控制器

class UsersController < ApplicationController


  def index
      @users = User.paginate(page: params[:page], :per_page => 5).includes(:profile)
  end

  def show
  if params[:id] 
      @user = User.find(params[:id])
      # .includes(:profile)
    else 
      @user = current_user
    end
    @searches = Search.where(user_id: @user).includes(:state, city: [:profile])
  end


  def new
    @user = User.new
    #@corporateprofile = Corporateprofile.new

  end

  def create
    @user = User.new(user_params)

    if @user.save
      session[:user_id] = @user.id
      redirect_to widgets_index_path
    else
      redirect to '/signup'
    end
  end

private
  def user_params
    params.require(:user).permit(:firstname, :lastname, :email, :password, :profile_type)
  end

end

并且控制器上没有传递代码(因为我坚​​持这样做)。任何更好的建议或解决此问题的方法将不胜感激!

干杯

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 polymorphic-associations


    【解决方案1】:

    首先,您要将个人资料类重命名为 StudentProfile 和 CorporateProfile。这将需要运行迁移来更改您的表名。

    这个问题的答案取决于您希望 StudentProfile 和 CorporateProfile 有多大的不同。如果它们完全不同甚至大部分不同,请将它们分开。如果它们大部分相同(换句话说,它们共享许多相同的方法),您应该创建一个 Profile(或 UserProfile)模型,并让 StudentProfile 和 CorporateProfile 从该模型继承。

    至于实现,应该是这样的:

    # user.rb
    class User < ActiveRecord::Base
      has_one :student_profile
      has_one :corporate_profile
    
      attr_accessor :profileable #probably change this to profile_type. Using attr_accessible because we want to use it during creation, but no need to save it on the user model, although it may not be a bad idea to create a column for user model and save this value.
    
      before_create :create_profile
    
      def create_profile
        if profileable == 1
          build_student_profile
        else
          build_corporate_profile
        end
      end
    end
    

    # student_profile.rb
    class StudentProfile < UserProfile # or possibly inherit from ActiveRecord::Base if not using inheritance
      belongs_to :user
    
      # other student profile stuff here
    end
    

    企业资料模型看起来与学生资料相同。

    此外,此时您应该使用 Rails 4,特别是如果您正在学习并且不了解控制器和参数,因为 Rails 3 和 4 之间有很大的不同。学习过时的东西没有用,对吧?


    编辑:我应该提一下,我不认为你理解 Rails 多态性。当一个模型属于多个模型时,它应该是多态的,当它有不同的子类时,不是

    例如,如果您的应用具有 Like 模型和其他类似 Post 模型的模型,并且用户可以喜欢其他用户的个人资料或帖子,这可能是多态性的良好候选者,因为 Like 可能属于 StudentProfiles 或 CorporateProfiles或帖子。

    【讨论】:

    • 啊,抱歉,尼克!我正在使用 rails 4,并且不小心检查了 Rails - 3 作为标签,这意味着您知道的“attr_accessible”不再有效。我已将逻辑移至控制器,因此 profile_type 是用户参数的一部分,但由于“UserProfile”是未初始化的常量而出现错误。
    • 糟糕,我的意思是把 attr_accessor 而不是 attr_accessible。现已编辑。如果你的控制器代码有问题,你也应该发布它,但听起来你还没有为 UserProfile 创建模型。
    • 啊哈,好吧,我已经用 attr_accessor 更新了我的代码。另请注意,我决定不实现 UserProfile 继承,因为这两个配置文件完全不同。我的挑战是始终生成公司资料,而不是学生资料。
    • 知道了!我的 profile_type 在迁移文件中设置为字符串,而不是整数,这不允许它获取模型代码。干杯尼克,你的传奇
    • 您的答案是一个答案,而不是答案。当您说“我认为您不了解 Rails 多态性”时,我认为您错了。这是具有多态配置文件的一个很好的用例,这意味着它可以以多种形式呈现(具有不同的属性)。这个视频在第 8 分钟左右很好地解释了这一点:railscasts.com/episodes/394-sti-and-polymorphic-associations
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    相关资源
    最近更新 更多