0

試圖使其創建時,根據用戶是選擇學生還是公司來創建用戶,Rails會爲該用戶創建學生配置文件或公司配置文件。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 

並且有在控制器上沒有通過代碼(如即時卡住上)。任何更好的建議或解決這個問題的方法將非常感謝!

乾杯

回答

2

首先,你要你的個人資料類重命名爲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或Posts。

+0

啊appologies尼克!我正在使用rails 4,並且意外地檢查了Rails - 3作爲標記,這意味着'attr_accessible'ias你知道不再有效。我已經將邏輯移動到控制器,以便profile_type是用戶參數的一部分,但是由於「UserProfile」是未初始化的常量而出現錯誤。 –

+0

糟糕,這意味着'attr_accessor'不是'attr_accessible'。現在編輯。如果你的控制器代碼有問題,你也應該發佈,但是聽起來你還沒有爲UserProfile創建一個模型。 –

+0

aha,好的,我已經用attr_accessor更新了我的代碼。另請注意,我決定不實施UserProfile繼承,因爲這兩個配置文件完全不同。我的挑戰是企業簡介始終在生成,而不是學生簡介。 –