Pt-G-3
Cliff Says
Here’s a stab at it. Generate a PaymentType model with a single string field.
rails generate model payment_type name:string
Add the three payment types in seeds.rb, and run rake db:seed.
PaymentType.create(:name => "Check")
PaymentType.create(:name => "Credit card")
PaymentType.create(:name => "Purchase order")
Add a names class method to the PaymentType model.
class PaymentType < ActiveRecord::Base
def self.names
all.collect { |payment_type| payment_type.name }
end
end
Change the validation in the Order model. Initially, one might do this:
validates :pay_type, :inclusion => PaymentType.names
Now I’m a Rails n00b, but as far as I can tell, doing validation that way would fetch the payment types just once from the DB at the moment when Ruby defines the Order model class. What if the payment types table in the DB is modified after the Order model class has been defined? Hence, I rewrote the validation to query the DB for the payment types every time the validation is called (at least, I think I did):
validates_each :pay_type do |model, attr, value|
if !PaymentType.names.include?(value)
model.errors.add(attr, "Payment type not on the list")
end
end
Then, in views/orders/_form.html.erb, replace
<%= f.select :pay_type, Order::PAYMENT_TYPES,
:prompt => 'Select a payment method' %>
with
<%= f.select :pay_type, PaymentType.names,
:prompt => 'Select a payment method' %>
Wham bam. Added some unit and functional tests too. Works fine. I’m not super satisfied with the messy-looking validates_each block, though. Anyone with a more elegant validation?
Older says (11/09/08)
Probably the best way to avoid later problems in case there is some payment method chances, would be to link an order’s payment method to the payment method’s id. This way, we can always change payment method names without having to update older orders. Then, it would be nice to migrate and add payment_method.id to order. Edit: I tried to but did not go well. I guess there is a way to deal with catalog table I don’t know yet.
h4. Ernesto says (14/09/2011)
rails generate migration add_pay_type_id_to_order pay_type_id:integer
rails generate scaffold pay_type name:string
rake db:migrate
than:
order.rb
has_one :pay_type
validates :pay_type_id, presence: true
pay_type.rb
belongs_to :orde
in app/views/orders/_form.html.erb
<div class="field">
<%= f.label :pay_type_id %><br />
<%= collection_select(:order, :pay_type_id, PayType.all, :id, :name) %>
</div>
You also need to edit the other views in app/views/orders….
more informations about: http://guides.rubyonrails.org/form_helpers.html starting at 3.2

