2015-01-12 19 views
0

我已经设置了一个Rails项目来使用Single Table Inheritance,因为我有User s - Sender s和Receiver s两​​种类型。 Sender s有public_key财产和Receiver s有phone_number财产。他们通过User共享name,emailpassword属性。Rails - 如何从单表继承创建正确类型的对象?

我的问题是,在User控制器的create功能,我试图创建一个类型或其他 - 无论是SenderReceiver - 基于单选按钮的我的注册表格上的数值。

这里的设置:

用户模型

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 

SENDER模型

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 

New User表单

<%= 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 %> 

User控制器的create方法,我试图与这if说法正确类型的User

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") %> 

但是,我总是else语句结束Sender类型对象。我在想这意味着我的if声明有错,if(user_type.eql? "receiver");然而,我无法弄清楚什么。

想法?

回答

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") %> 

声明:未经测试,但它应该照顾你的问题。

+0

你说得对,那是正确的 –