0

Попытка сделать так, чтобы при создании пользователя, исходя из того, выбираются ли они студентом или корпорацией, рельсы создадут этого пользователя как профиль студента, так и корпоративный профиль.Rails - Полиморфная ассоциация для создания различных профилей

Ive попытался настроить его с помощью политик Polymorphic, но не смог определить, как создать профиль на уровне модели, исходя из того, что выбрано в представлении.

Модели

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 на этом этапе, особенно если вы изучаете и не понимаете контроллеры и параметры, так как это довольно разные между рельсами 3 и 4. Нет смысла изучать что-то устаревшее, правильно?


Редактировать: Следует упомянуть, что я не понимаю, что вы понимаете полиморфизм рельсов. Модель должна быть полиморфной, если она будет принадлежать нескольким моделям, не, когда у нее будут разные подклассы.

Например, если у вашего приложения есть модель Like и что-то еще, например, модель Post, и пользователю могут нравиться профили или сообщения других пользователей, это может быть хорошим кандидатом для полиморфизма, поскольку Like может принадлежать StudentProfiles или CorporateProfiles или сообщения.

+0

Агонизирует ник! Я использую рельсы 4 и случайно проверял Rails-3 как тег, что означает 'attr_accessible ', который, как вы знаете, больше не работает. Я переместил логику на контроллер, так что profile_type является частью пользовательских параметров, но я получаю ошибки, когда «UserProfile» является неинициализированной константой. –

+0

К сожалению, это означает, что 'attr_accessor' не' attr_accessible'. Отредактировано сейчас. Если у вас возникли проблемы с кодом вашего контроллера, вы также должны опубликовать его, но похоже, что вы еще не создали модель UserProfile. –

+0

aha, хорошо, поэтому я обновил свой код с помощью attr_accessor. Также обратите внимание: я решил не реализовывать наследование UserProfile, так как два профиля совершенно разные. Моя задача заключается в том, что корпоративный профиль всегда создается, а не профиль студента. –

Смежные вопросы