# Polymorphic Associations - Customer & Supplier have Phones

**URL:** <https://www.ruby-forum.com/t/polymorphic-associations-customer-supplier-have-phones/225977>\
**Category:** Rails\
**Created:** [November 2, 2007, 12:38pm UTC](https://www.ruby-forum.com/t/polymorphic-associations-customer-supplier-have-phones/225977 "2007-11-02T12:38:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jmaenpaa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de053/32.png) [@jmaenpaa](https://www.ruby-forum.com/u/jmaenpaa)\
**Post date:** [November 2, 2007, 12:38pm UTC](https://www.ruby-forum.com/t/polymorphic-associations-customer-supplier-have-phones/225977/1 "2007-11-02T12:38:13Z")

</div>

INTRO

I am currently working for a company who want a new e-commerce  
interface; I have considered using ruby on rails. I am completely stuck  
I donâ€™t know what has gone wrong I am trying to create customers or  
suppliers numbers and it wont do anything, it will actually ignore the  
data I input and just show blank without any errors. Hopefully this  
example can help others in the future if they want to do something  
similar what I have.

SCENARIO

I have four tables, which are

- Addresses
- Customers
- Suppliers
- Phones

I have used polymorphic association because a customer and a supplier  
can have more than one or many addresses and phone numbers etc. So I  
basically created my tables using Migration, then used ruby Scaffold to  
create models, views etc. This is how I have created the relationships  
note that I am currently just going to focus on the phones table with  
customer or supplier once I have this right I can easily do the  
addresses:

Phones Table:

class CreatePhones \< ActiveRecord::Migration  
def self.up  
create\_table :phones do |t|  
t.column :created\_at, :datetime  
t.column :updated\_at, :datetime  
t.column :phonable\_id, :integer, :null =\> false  
t.column :phonable\_type, :string, :null =\> false  
t.column :tag\_for\_phone, :string # could be “work phone”, “home  
phone”, etc  
t.column :number, :string # redundant but makes searching easier  
t.column :country\_code, :string  
t.column :area\_code, :string  
t.column :local\_number, :string

```
end
add_index :phones, :number # don't make this unique!

```

end

def self.down  
drop\_table :phones  
end  
end

Customer Table:

class CreateCustomers \< ActiveRecord::Migration  
def self.up  
create\_table :customers do |t|  
t.column :first\_name, :string  
t.column :surname, :string  
end  
end

def self.down  
drop\_table :customers  
end  
end

Supplier Table:

class CreateSuppliers \< ActiveRecord::Migration  
def self.up  
create\_table :suppliers do |t|  
t.column :name, :string  
end  
end

def self.down  
drop\_table :suppliers  
end  
end

Here are the relationships between tables:

Phones Model:

class Phone \< ActiveRecord::Base  
belongs\_to :phonable, :polymorphic =\> true  
has\_one :customer, :as =\> :phonable  
has\_one :supplier, :as =\> :phonable  
end

Customer Model:

class Customer \< ActiveRecord::Base  
has\_many :phones, :as =\> :phonable, :dependent =\> :destroy  
has\_many :addresses, :as =\> :addressable, :dependent =\> :destroy

def full\_name  
“#{first\_name} #{surname}”  
end  
end

Supplier Model:

class Supplier \< ActiveRecord::Base  
has\_many :phones, :as =\> :phonable, :dependent =\> :destroy  
has\_many :addresses, :as =\> :addressable, :dependent =\> :destroy

def full\_name  
name  
end  
end

Now here are the controllers that I have used:

Phones Controller:

class PhonesController \< ApplicationController  
def index  
list  
render :action =\> ‘list’  
end

# GETs should be safe (see

[URIs, Addressability, and the use of HTTP GET and POST](http://www.w3.org/2001/tag/doc/whenToUseGet.html))  
verify :method =\> :post, :only =\> [:destroy, :create, :update],  
:redirect\_to =\> { :action =\> :list }

def list  
@phone\_pages, @phones = paginate :phones, :per\_page =\> 10  
end

def show  
@phone = Phone.find(params[:id])  
end

def new  
@customer = Customer.find(params[:customer\_id]) if  
params[:customer\_id]  
@supplier = Supplier.find(params[:supplier\_id]) if  
params[:supplier\_id]  
@phone = Phone.new  
end

def create  
@customer = Customer.find(params[:customer][:id]) if  
params[:customer]  
@supplier = Supplier.find(params[:supplier][:id]) if  
params[:supplier]  
@phone = Phone.new(params[:phone])  
@phone.number = “+#{@phone.country\_code} #{@phone.area\_code}  
#{@phone.local\_number}”  
respond\_to do |format|  
if @phone.save  
@customer.phones \<\< @phone if @customer  
@supplier.phones \<\< @phone if @supplier  
@customer.save if @customer  
@supplier.save if @supplier  
flash[:notice] = “Successfully added #{@phone.number}.”  
format.html { redirect\_to phone\_url(@phone) }  
format.xml { head :created, :location =\> phone\_url(@phone) }  
else  
flash[:notice] = “Unable to add #{@phone.number}.”  
format.html { render :action =\> “new” }  
format.xml { render :xml =\> @phone.errors.to\_xml }  
end  
end  
end

def edit  
@phone = Phone.find(params[:id])  
end

def update  
@phone = Phone.find(params[:id])  
if @phone.update\_attributes(params[:phone])  
flash[:notice] = ‘Phone was successfully updated.’  
redirect\_to :action =\> ‘show’, :id =\> @phone  
else  
render :action =\> ‘edit’  
end  
end

def destroy  
Phone.find(params[:id]).destroy  
redirect\_to :action =\> ‘list’  
end  
end

Customers Controller:

class CustomersController \< ApplicationController  
def index  
list  
render :action =\> ‘list’  
end

# GETs should be safe (see

[URIs, Addressability, and the use of HTTP GET and POST](http://www.w3.org/2001/tag/doc/whenToUseGet.html))  
verify :method =\> :post, :only =\> [:destroy, :create, :update],  
:redirect\_to =\> { :action =\> :list }

def list  
@customer\_pages, @customers = paginate :customers, :per\_page =\> 10  
end

def show  
@customer = Customer.find(params[:id])  
end

def new  
@customer = Customer.new  
end

def create  
@customer = Customer.new(params[:customer])  
if @customer.save  
flash[:notice] = ‘Customer was successfully created.’  
redirect\_to :action =\> ‘list’  
else  
render :action =\> ‘new’  
end  
end

def edit  
@customer = Customer.find(params[:id])  
end

def update  
@customer = Customer.find(params[:id])  
if @customer.update\_attributes(params[:customer])  
flash[:notice] = ‘Customer was successfully updated.’  
redirect\_to :action =\> ‘show’, :id =\> @customer  
else  
render :action =\> ‘edit’  
end  
end

def destroy  
Customer.find(params[:id]).destroy  
redirect\_to :action =\> ‘list’  
end  
end

Suppliers Controller:

class SuppliersController \< ApplicationController  
def index  
list  
render :action =\> ‘list’  
end

# GETs should be safe (see

[URIs, Addressability, and the use of HTTP GET and POST](http://www.w3.org/2001/tag/doc/whenToUseGet.html))  
verify :method =\> :post, :only =\> [:destroy, :create, :update],  
:redirect\_to =\> { :action =\> :list }

def list  
@supplier\_pages, @suppliers = paginate :suppliers, :per\_page =\> 10  
end

def show  
@supplier = Supplier.find(params[:id])  
end

def new  
@supplier = Supplier.new  
end

def create  
@supplier = Supplier.new(params[:supplier])  
if @supplier.save  
flash[:notice] = ‘Supplier was successfully created.’  
redirect\_to :action =\> ‘list’  
else  
render :action =\> ‘new’  
end  
end

def edit  
@supplier = Supplier.find(params[:id])  
end

def update  
@supplier = Supplier.find(params[:id])  
if @supplier.update\_attributes(params[:supplier])  
flash[:notice] = ‘Supplier was successfully updated.’  
redirect\_to :action =\> ‘show’, :id =\> @supplier  
else  
render :action =\> ‘edit’  
end  
end

def destroy  
Supplier.find(params[:id]).destroy  
redirect\_to :action =\> ‘list’  
end  
end

This is my phones helper:

module PhonesHelper

def phonable\_path(phonable)  
if phonable.kind\_of? Customer  
customer\_path(phonable)  
else  
supplier\_path(phonable)  
end  
end  
end

Now for the pages I have used the following code and what happens is  
that I try to add a phone number for the customer and it wont add the  
telephone number at all I have tried everything:

Customers View Show:

\<% unless @user.phones.empty? %\>  
Phone Numbers  
\<% for phone in @customer.phones %\>  
\<%= link\_to phone.number, phone\_path(phone) %\>  
  
\<% end %\>  
\<% end %\>

  
\<%= link\_to 'Add Phone Number', new\_user\_phone\_path(@user) %\>  

Phones View New:

# New Phone Number
For \<%=h @customer.full\_name if @customer -%\> \<%=h @supplier.full\_name if @supplier -%\>  
\<% form\_for :phone, :url =\> phones\_path do |form| -%\> \<%= (hidden\_field :customer, :id, :value =\> @customer.id) if @customer -%\> \<%= (hidden\_field :supplier, :id, :value =\> @supplier.id) if @supplier -%\> \<%= render :partial =\> 'form', :object =\> form -%\>

\<%= submit\_tag 'Create' -%\>

\<% end -%\>

Phones View Show:

\<% if @phone.phonable\_type == ‘Customer’ -%\>  
Phone for  
  
\<%= link\_to @phone.phonable.full\_name, phonable\_path(@phone.phonable)  
-%\>  
  
   
\<% end -%\>  
  
\<% if @phone.phonable\_type == ‘Supplier’ -%\>  
Phone for  
  
\<%= link\_to @phone.phonable.full\_name, supplier\_path(@phone.phonable)  
-%\>  
  
   
\<% end -%\>

Phones View \_form :

\<%= error\_messages\_for ‘phone’ %\>

\<%= form.hidden\_field :phonable\_type %\>  
\<%= form.hidden\_field :phonable\_id %\>

Created at  
\<%= datetime\_select 'phone', 'created\_at' %\>

Updated at  
\<%= datetime\_select 'phone', 'updated\_at' %\>

Tag for phone  
\<%= text\_field 'phone', 'tag\_for\_phone' %\>

Number  
\<%= text\_field 'phone', 'number' %\>

Country code  
\<%= text\_field 'phone', 'country\_code' %\>

Area code  
\<%= text\_field 'phone', 'area\_code' %\>

Local number  
\<%= text\_field 'phone', 'local\_number' %\>

Routes:

map.resources :addresses  
map.resources :phones  
map.resources :suppliers do |supplier|  
supplier.resources :supplier\_phones,  
:opaque\_name =\> :phones,  
:controller =\> :phones  
supplier.resources :supplier\_addresses,  
:opaque\_name =\> :addresses,  
:controller =\> :addresses  
end  
map.resources :customers do |customer|  
customer.resources :customer\_phones,  
:opaque\_name =\> :phones,  
:controller =\> :phones  
customer.resources :customer\_addresses,  
:opaque\_name =\> :addresses,  
:controller =\> :addresses  
end  
end

Ok so thats it then, I have attached a word document if you want things  
to be clearly labelled, please can someone help me to complete this  
tricky situation thank you!!!
