Rails - 创建不同配置文件的多态关联

时间:2016-03-06 04:07:17

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

尝试创建用户时,根据他们是选择成为学生还是公司,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

控制器上没有传递代码(因为我坚​​持这个)。任何更好的建议或方法来解决这个问题将非常感激!

干杯

1 个答案:

答案 0 :(得分:2)

首先,您要将配置文件类重命名为StudentProfile和CorporateProfile。这将需要运行迁移以更改您的表名。

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

至于实现,它应该看起来像这样:

onCreate()
# 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

公司简介模型看起来与学生档案相同。

此外,此时您应该使用Rails 4,特别是如果您正在学习并且不了解控制器和参数,因为在第3和第4轨之间这是非常不同的。在学习某些东西时没有用那已经过时了,对吧?

编辑:我应该提一下,我不了解你的轨道多态性。当模型属于多个模型时,模型应该是多态的,当它具有不同的子类时,

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