Hello,
I am fairly new to RoR and I have a question I hope can be solved
elegantly (so many things are, so why not this one too?). I have a
working solution, but I want to be sure I am doing things the “rails
way” (having come from PHP). You could say I am looking for a little
validation (no flames please).
I have a table of units like so:
CREATE TABLE units
(
id
int(11) NOT NULL auto_increment,
number
varchar(255) NOT NULL default ‘’,
description
text NOT NULL,
PRIMARY KEY (id
)
) TYPE=MyISAM;
that has_many :prices like so:
CREATE TABLE prices
(
id
int(11) NOT NULL auto_increment,
price
decimal(10,2) NOT NULL default ‘0.00’,
unit_id
int(11) default NULL,
created_at
datetime NOT NULL default ‘0000-00-00 00:00:00’,
PRIMARY KEY (id
),
KEY unit_id
(unit_id
)
) TYPE=MyISAM;
My goal is to be able to create a unit and set its price at the same
time. Then, when I update a unit, should I change the price, I want
to add a new row and time stamp to the price table.
My unit model looks like this:
class Unit < ActiveRecord::Base
has_many :prices
has_one :most_recent_price, :class_name => “Price”, :order =>
‘created_at DESC’
end
The has_one :most_recent_price lets me grab the most recent price for
display and comparison purposes.
I can currently accomplish my aims in the controller like so:
class AdminUnitsController < ApplicationController
#snip
def create
@unit = Unit.new(params[:unit])
@unit.prices.create(“price” => params[:price])
@levels = Level.find(:all, :order => “LPAD
(levels
.elevator_number
,5,“0”) ASC”)
@unit_types = UnitType.find(:all, :order => “unit_types
.name
ASC”)
if @unit.save
Unit.find(@unit.id).update_attributes(params[:unit])
flash[:notice] = ‘Unit was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end
def update
@unit = Unit.find(params[:id])
unless params[:price] == @unit.most_recent_price.price.to_s
@unit.prices.build(“price” => params[:price])
end
@levels = Level.find(:all, :order => “LPAD
(levels
.elevator_number
,5,“0”) ASC”)
@unit_types = UnitType.find(:all, :order => “unit_types
.name
ASC”)
if @unit.update_attributes(params[:unit])
flash[:notice] = ‘Unit was successfully updated.’
redirect_to :action => ‘show’, :id => @unit
else
render :action => ‘edit’
end
end
#snip
end
and a _form.rhtml like so:
<%= error_messages_for ‘unit’ %>
Number
<%= text_field 'unit', 'number' %>
Description
<%= text_area 'unit', 'description' %>
Base Price
$<%= text_field_tag 'price', @unit.most_recent_price.nil? ? "0.00" :
@unit.most_recent_price.price %>
Is this the “rails way”? Is there a better way?
Specifically, is the text_field_tag ‘price’ construct the best way to
show/capture the price value or is there a “rails way” of showing/
capturing the price value and capturing it with params[] that I don’t
know about? If there isn’t, would it be best to move the ternary
operator statement into the model or is kosher to keep it in the view?
Thanks for any input,
Nick