Reputation: 1275
I've set up a Rails project to use Single Table Inheritance because I have two types of User
s - Sender
s and Receiver
s. Sender
s have a public_key
property and Receiver
s have a phone_number
property. They share name
, email
, and password
properties through User
.
My issue is that in the create
function of the User
controller, I'm trying to create one type or the other - either a Sender
or Receiver
- based on the value of a radio button on my signup form.
Here's the setup:
USER MODEL
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 MODEL
class Sender < User
validates :public_key, :presence => true
end
RECEIVER MODEL
class Receiver < User
validates :phone_number, :presence => true, :length => 10
end
USER CONTROLLER
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
<%= 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 %>
In the create
method of the User
controller, I'm trying to make the correct type of User
with this if
statement:
if(user_type.eql? "receiver")
@user = Receiver.new(user_params)
else
@user = Sender.new(user_params)
based on the value recorded in the User
form here:
<%= 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") %>
However, I always wind up with a Sender
type object from the else
statement. I'm thinking this means something is wrong with my if
statement, if(user_type.eql? "receiver")
; however, I cannot figure out what.
Thoughts?
Upvotes: 0
Views: 65
Reputation: 1954
First of all, I think you do not need set_user_type
method because you are not using the @user_type
variable that its setting. Take out before_action
from top of the controller as well.
Second, in user_type
method you need to change params[:type]
to params[:user_type]
since that's the name of radio button tags in HTML.
def user_type
User.user_types.include?(params[:user_type]) ? params[:user_type] : "User"
end
Third, you also need to capitalize the value attributes of radio button tags to "Sender" and "Receiver", because thats what you have in User.user_types
array.
<%= radio_button_tag(:user_type, "Sender") %>
<%= radio_button_tag(:user_type, "Receiver") %>
Disclaimer: Not tested, but it should take care of your issues.
Upvotes: 1