Rails - Как создать правильный тип объекта из наследования одной таблицы?

Я настроил проект Rails для использования наследования одной таблицы, потому что у меня есть два типа Users — Senders и Receivers. Sender имеют свойство public_key, а Receiver имеют свойство phone_number. Они разделяют свойства name, email и password через User.

Моя проблема в том, что в функции create контроллера User я пытаюсь создать тот или иной тип — либо Sender, либо Receiver — на основе значения переключателя в моей форме регистрации.

Вот настройка:

ПОЛЬЗОВАТЕЛЬСКАЯ МОДЕЛЬ

class User < ActiveRecord::Base

  validates :name,  :presence => true, :length => { maximum: 50 }
  validates :password, presence: true

  self.inheritance_column = :user_type

  # We will need a way to know which types with subclass the User model
  def self.user_types
    %w(Sender Receiver)
  end
end

class Sender < User; end
class Receiver < User; end

МОДЕЛЬ ОТПРАВИТЕЛЯ

class Sender < User
  validates :public_key,  :presence => true
end

МОДЕЛЬ ПРИЕМНИКА

class Receiver < User
  validates :phone_number,  :presence => true, :length => 10
end

КОНТРОЛЛЕР ПОЛЬЗОВАТЕЛЯ

class UsersController < ApplicationController
  #  before_action :set_user, only: [:show, :edit, :update, :destroy]
  before_action :set_user_type

  def index
    @users = user_type_class.all
  end

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def create
    if(user_type.eql? "receiver")
      @user = Receiver.new(user_params)
    else
      @user = Sender.new(user_params)
  end
  ...
  private

    # allow views to access user_type
    def set_user_type
      @user_type = user_type
    end

    def user_type
      User.user_types.include?(params[:type]) ? params[:type] : "User"
    end

    def user_type_class
      user_type.constantize
    end

    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end

    def user_params
      params.require(:user).permit(:name, :email, :password, :confirmation_password, :user_type)
    end
end

НОВАЯ ПОЛЬЗОВАТЕЛЬСКАЯ ФОРМА

<%= form_for(@user) do |f| %>
...
  <div class="user-type">
    <%= f.label :user_type, class: 'form-control' %>
    <%= radio_button_tag(:user_type, "sender")  %>
    <%= label_tag(:user_type_sender, "I am a Sender")  %>
    <%= radio_button_tag(:user_type, "receiver")  %>
    <%= label_tag(:user_type_receiver, "I am a Receiver")  %>
  </div>
  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
 ...
<% end %>

В методе create контроллера User я пытаюсь сделать правильный тип User с помощью этого оператора if:

if(user_type.eql? "receiver")
  @user = Receiver.new(user_params)
else
  @user = Sender.new(user_params)

на основе значения, записанного в форме User здесь:

<%= radio_button_tag(:user_type, "sender")  %>
<%= label_tag(:user_type_sender, "I am a Sender")  %>
<%= radio_button_tag(:user_type, "receiver")  %>
<%= label_tag(:user_type_receiver, "I am a Receiver")  %>

Однако я всегда получаю объект типа Sender из оператора else. Я думаю, это означает, что что-то не так с моим if утверждением, if(user_type.eql? "receiver"); однако я не могу понять, что.

Мысли?


person H K    schedule 12.01.2015    source источник


Ответы (1)


Прежде всего, я думаю, вам не нужен метод set_user_type, потому что вы не используете переменную @user_type, которая его устанавливает. Выньте before_action из верхней части контроллера.

Во-вторых, в методе user_type вам нужно изменить params[:type] на params[:user_type], так как это имя тегов переключателей в HTML.

def user_type
  User.user_types.include?(params[:user_type]) ? params[:user_type] : "User"
end

В-третьих, вам также необходимо использовать атрибуты значений тегов переключателей для «Отправитель» и «Получатель», потому что это то, что у вас есть в массиве User.user_types.

<%= radio_button_tag(:user_type, "Sender")  %>
<%= radio_button_tag(:user_type, "Receiver")  %>

Отказ от ответственности: не тестировалось, но должно решить ваши проблемы.

person San    schedule 12.01.2015