Advice on model design


#1

I’ve got an application with 2 related models. I want to search for
data based on conditions in both models. I want to return items from
the first model (Contract) grouped by conditions in the second
(Status)

At the moment, I’m basically doing it as shown below. It seems really
ugly. Any suggestions how to do it better? Thanks
Nick

class Contract < ActiveRecord::Base
belongs_to :project
belongs_to :status

def self.activity_find(team, director)
conditions = Array.new
conditions << “projects.team_id = #{service_team}” if
service_team != “0”
conditions << “projects.director_id = #{bid_director}” if
bid_director != “0”
ces = Array.new
for group in Status::GROUPS
conditions << “statuses.” + Status.group_sql(group)
status_group = find(:all, :conditions => conditions.join(" AND
"), :include => [:status])
conditions.delete( conditions.last )
ces << {:data => status_group, :name => group[:description]}
end
end
end

class Status < ActiveRecord::Base
has_many :contracts

GROUPS = [{:stage => 1, :description => “been entered as
prospect”},
{:stage => 2, :description => “proposal has been
submitted”},
{:stage => 3, :description => “been notified as won”},
{:stage => 4, :description => “been contracted”}]

def self.group_sql(group)
case group[:stage]
when 1 then ‘opportunity=1’
when 2 then ‘confirmed=1’
when 3 then ‘notified=1’
when 4 then ‘contracted=1’
end
end


#2

Hi!
At first read this article
http://spin.atomicobject.com/2008/06/16/finder-objects-in-rails
About Status model, at my mind is unnecessary. You can create status
field in Contracts table

About:
GROUPS = [{:stage => 1, :description => “been entered as
prospect”},
{:stage => 2, :description => “proposal has been
submitted”},
{:stage => 3, :description => “been notified as won”},
{:stage => 4, :description => “been contracted”}]

In our project, such things we move to presenters
in Contract:
compose_of :status, :class_name => ‘ContractStatus’, :mapping => %
(status to_i) do |value|
ContractStatus.new(value)
end
scopes_state :status, :with => ContractStatus::STATUSES (see
http://giantrobots.thoughtbot.com/2008/10/14/life-in-the-fast-lane)

in presenter ContractStatus:

STATUSES = [:notified_as_won, :submitted, contracted]
HUMANIZE_STATUSES =
{
:notified_as_won => ‘been notified as won’,
:submitted =>‘proposal has been submitted’
}

def initialize(value)
@int_status =
case value
when Symbol
STATUSES.index(value)
when Integer
value
else
raise
end
end

#show in view
def to_s
HUMANIZE_STATUSES[self.to_sym]
end

def to_sym
STATUSES.at(self.to_i)
end

#save in db
def to_i
STATUSES[@int_status]
end

Good luck!


#3

Faust, sorry for the slow reply but thanks for your help!
Nick