Hello--
There must be a better way to do this. I have a class method in my model
that finds averages and does a few calculations using find_by_sql. The
problem I¹m encountering is that all computed columns from MySQL come back
as type string. E.g.,
def self.find_averages(domain_id)
if @@domain_average
return @@domain_average
else
@@domain_average = MyDomain.find_by_sql(["select avg(latency) as
latency, avg(datediff(session_end, session_start)) as session_duration from
live_logs where domain_id=?"], domain_id])[0]
end
end
The problem is that I¹m using a lot of to_f conversions because type
coercions are not happening as I would have expected. Again, for example:
foo = MyDomain.find_averages(1)
bar = foo[:latency] / 3.0 # fails because foo[:latency] is a string and
Ruby won¹t do the coercion
zoo = foo[:latency].to_f / 3.0 # succeeds because I did the coercion
explicitly, but code is more brittle
Does anyone have a thought has to how this might better be achieved?
Thanks
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails
You need to provide manual casting of these types. The preferred mechanism
is to override the default accessors:
Class MyDomain < ActiveRecord::Base
def latency
Float(read_attribute("latency"))
end
end
Then you can write your code:
bar = foo.latency / 3.0
I just re-read this section of the Ruby on Rails book..
_____
From: Steve Ross
[mailto:sross-ju+vs0qJmycyYsO2DCxJlVaTQe2KTcn/@public.gmane.org]
Sent: Friday, October 28, 2005 2:30 PM
To: rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
Subject: [Rails] find_by_sql column types
Hello--
There must be a better way to do this. I have a class method in my model
that finds averages and does a few calculations using find_by_sql. The
problem I''m encountering is that all computed columns from MySQL come
back
as type string. E.g.,
def self.find_averages(domain_id)
if @@domain_average
return @@domain_average
else
@@domain_average = MyDomain.find_by_sql(["select avg(latency) as
latency, avg(datediff(session_end, session_start)) as session_duration from
live_logs where domain_id=?"], domain_id])[0]
end
end
The problem is that I''m using a lot of to_f conversions because type
coercions are not happening as I would have expected. Again, for example:
foo = MyDomain.find_averages(1)
bar = foo[:latency] / 3.0 # fails because foo[:latency] is a string and
Ruby won''t do the coercion
zoo = foo[:latency].to_f / 3.0 # succeeds because I did the coercion
explicitly, but code is more brittle
Does anyone have a thought has to how this might better be achieved?
Thanks
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails
This should work:
@@domain_average = MyDomain.find_by_sql(["select avg(latency) as
latency from live_logs where domain_id=?",
domain_id])[0][''latency''].to_f
-lv
Steve Ross wrote:
> Hello--
>
> There must be a better way to do this. I have a class method in my model
> that finds averages and does a few calculations using find_by_sql. The
> problem I’m encountering is that all computed columns from MySQL come
> back as type string. E.g.,
>
> def self.find_averages(domain_id)
> if @@domain_average
> return @@domain_average
> else
> @@domain_average = MyDomain.find_by_sql(["select avg(latency)
as
> latency, avg(datediff(session_end, session_start)) as session_duration
> from live_logs where domain_id=?"], domain_id])[0]
> end
> end
...
Except that this only works where find_by_sql is returning one column. My find is returning about seven. I''ve settled on: @@domain_average.foo = @@domain_average.foo.to_f @@domain_average.bar = @@domain_average.bar.to_f at the end of my get_averages() function. Somehow, it seems like a hack. Comments? On 10/28/05 3:06 PM, "Lou Vanek" <vanek-9H8CmIPm+GA@public.gmane.org> wrote:> This should work: > > @@domain_average = MyDomain.find_by_sql(["select avg(latency) as > latency from live_logs where domain_id=?", domain_id])[0][''latency''].to_f > > -lv > > Steve Ross wrote: > >> Hello-- >> >> There must be a better way to do this. I have a class method in my model >> that finds averages and does a few calculations using find_by_sql. The >> problem I¹m encountering is that all computed columns from MySQL come >> back as type string. E.g., >> >> def self.find_averages(domain_id) >> if @@domain_average >> return @@domain_average >> else >> @@domain_average = MyDomain.find_by_sql(["select avg(latency) as >> latency, avg(datediff(session_end, session_start)) as session_duration >> from live_logs where domain_id=?"], domain_id])[0] >> end >> end > ... > >
any number of fields can be returned at one time because find_by_sql returns
an array of hashes. An example with two fields returned:
record = MyDomain.find_by_sql(["select avg(latency) as
latency, avg(field2) as avgfld2 from live_logs where
domain_id=?", domain_id])[0]
@@domain_average = record[''latency''].to_f
@@avgfld2 = record[''avgfld2''].to_f
Steve Ross wrote:
> Except that this only works where find_by_sql is returning one column. My
> find is returning about seven. I''ve settled on:
>
> @@domain_average.foo = @@domain_average.foo.to_f
> @@domain_average.bar = @@domain_average.bar.to_f
>
> at the end of my get_averages() function.
>
> Somehow, it seems like a hack.
>
> Comments?
>
>
> On 10/28/05 3:06 PM, "Lou Vanek"
<vanek-9H8CmIPm+GA@public.gmane.org> wrote:
>
>
>>This should work:
>>
>>@@domain_average = MyDomain.find_by_sql(["select avg(latency) as
>> latency from live_logs where domain_id=?",
domain_id])[0][''latency''].to_f
>>
>>-lv
>>
>>Steve Ross wrote:
>>
>>
>>>Hello--
>>>
>>>There must be a better way to do this. I have a class method in my
model
>>>that finds averages and does a few calculations using find_by_sql.
The
>>>problem I¹m encountering is that all computed columns from MySQL
come
>>>back as type string. E.g.,
>>>
>>>def self.find_averages(domain_id)
>>> if @@domain_average
>>> return @@domain_average
>>> else
>>> @@domain_average = MyDomain.find_by_sql(["select
avg(latency) as
>>>latency, avg(datediff(session_end, session_start)) as
session_duration
>>>from live_logs where domain_id=?"], domain_id])[0]
>>> end
>>>end
>>
>>...
>>
>
>