I have a problem regarding an algorith, for a record I am looking for.
I can do it in straight sql statements, but I am certain there is a
Ruby "idion" for this (which, coming from another language, is the
hardest thing about this fantastic language, getting a handle on the
idiomsm the syntactic sugars).
I have an id for an associate ('my_associate_id') and I want to
determine if my associate is in this table with a given channel_id (my
channel_id) and if not, to select the associate_id in this list whose
channel_id matches my_channel_id with the lowest batting order.
Doing this in a couple of sql statements is quite trivial -- but is
there a way to do it in a purely Ruby-like idiom?
See, I don't htink there IS an easier way -- just a Ruby-occluded way
called .find_by_sql(["select ..."])
A lot of this syntactic sugar really gets in the way. Rails is great,
as a web framework -- far superior to something like Struts. But in
the end, it;s back to JRuby, writing the back end in the C-like
syntax of Java, and avoiding Ruby and it's idioms, making use of Rails
this way.
Yes, ORMs are wonderful, once you learn the abstraction layer. But --
and I know some will take offense at this -- there are things to avoid
in learning Ruby, and just use the old tried-n-true (many things, like
using straight Javascript for most of the Ajax-like things you want to
do, or for db-query-b ased algorithms, like I am trying to accomplish
here, sticking with as straight of an sql interface as possible). This
is true of most languages, if you can learn a more generic means of
implementing the language, you are not only up-to-speed faster, BUT,
you generally have a finer-grained control over what you ware
implementing.
The algorithm I am looking to sweeten of:
# Is the associate in the list - if not, make it the person at
the top of the list.
@up = Up.find(params[:id]) #get the individual up record which
has the associate and channel
@associate = @up.associate#specify ref to the associate in question
#see if this associate is in the current list
@Qplayers = Qplayer.find_by_sql(["select * from qplayers where
associate_id=? and channel_id=? and
inlist=1",@associate.id,@associate.channel_id])
if @Qplayers[0].blank? #if the associate from the up in the row is in
the list, it wont be blank
@Qplayers = Up.find_by_sql(["select * from qplayers where
channel_id=? and inlist=1 order by battingorder ASC",@up.channel_id])
@Qplayer = @Qplayers[0]
@associate = @Qplayer.associate
end
I'm not sure can be more clearly expressed in a "sweeter" way,
especially if the criteria changes in the future -R.Vince
Yes, ORMs are wonderful, once you learn the abstraction layer. But --
and I know some will take offense at this -- there are things to avoid
in learning Ruby, and just use the old tried-n-true (many things, like
using straight Javascript for most of the Ajax-like things you want to
do, or for db-query-b ased algorithms, like I am trying to accomplish
here, sticking with as straight of an sql interface as possible). This
is true of most languages, if you can learn a more generic means of
implementing the language, you are not only up-to-speed faster, BUT,
you generally have a finer-grained control over what you ware
implementing.
The algorithm I am looking to sweeten of:
\# Is the associate in the list \- if not, make it the person at
the top of the list.
@up = Up.find(params[:id]) #get the individual up record which
has the associate and channel
@associate = @up.associate#specify ref to the associate in question
#see if this associate is in the current list
@Qplayers = Qplayer.find_by_sql(["select * from qplayers where
associate_id=? and channel_id=? and
inlist=1",@associate.id,@associate.channel_id])
if @Qplayers\[0\]\.blank? \#if the associate from the up in the row is in
the list, it wont be blank
@Qplayers = Up.find_by_sql(["select * from qplayers where
channel_id=? and inlist=1 order by battingorder ASC",@up.channel_id])
@Qplayer = @Qplayers[0]
@associate = @Qplayer.associate
end
I'm not sure can be more clearly expressed in a "sweeter" way,
especially if the criteria changes in the future -R.Vince
I wouldn't resort to find_by_sql for this - just a normal find :all
keeps things clean, and plays nicely with scopes and so on. It seems
to me that you could make this a little more succinct by playing
around with named_scope and similar tools, eg add
named_scope :in_list, :conditions => {:inlist => true}
named_scope :in_channel, lambda {|channel_id| {:conditions =>
{:channel_id => channel_id}}}
to Qplayer
And then you can write something like
@qplayer = @associate.q_players.in_list.in_channel
(@associate.channel_id).first
if !@qplayer@qplayer = Qplayer.inlist.in_channel
(@up.channel_id).find :first, :order -> 'batting_order asc'
end