ActiveRecord (1.1) question

R

Raif S. Naffah

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

hello all,

i wrote a collection of Ruby classes to analyse the log entries
generated by a Billion firewall/router. The script, persists the
_attack_ information in an RDBMS through Active Record (version 1.1).

both myself and a colleague, use the same code, on two different
machines + setup. i use it with:

* Fedora Core 2 GNU/Linux distro,
* ruby 1.8.1 (2003-12-25) [i386-linux-gnu]
* PostGreSQL 7.4

he uses it with:

* Debian distro,
* ruby 1.8.2 (2004-11-03) [i386-linux]
* libmysql-ruby1.8 : 2.4.5-6

the classes run fine in my environment, but throw the following
exception in his:

/usr/local/lib/site_ruby/1.8/active_record/base.rb:817:in `method_missing': undefined method `min' for #<Attack:0x4035a2d8> (NoMethodError)
~ from ./analyser.rb:28:in `analyse'
~ from ./analyser.rb:198:in `run'
~ from ./logan.rb:53:in `run'
~ from ./logan.rb:61

the line in question looks like so:

at = Attack.find_by_sql(\
"SELECT MIN(occured_on) " +\
"FROM attacks " +\
"WHERE occured_on BETWEEN '#{start_date_str}' AND '#{end_date_str}'")[0].min


the Attack class is defined as:

class Attacker < ActiveRecord::Base
has_many :attacks
has_many :black_listings
end

trying to find out more how the 'at' object (instance of Attack) looks
like when the exception is thrown, reveals an object with an instance
attribute that looks like so:

@attribute {"MIN(occured_on)"=>"some date..."}


any idea why this is happening? and, most importantly if he is missing
some library, which one is it?


TIA + cheers;
rsn
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Que du magnifique

iD8DBQFBpue0+e1AKnsTRiERA7zMAKCggpo00bs6YkkrV6/QmFCod6AGRACg1DQ9
y5Ob5zLbKxwaEuVCFqUocCY=
=hG/K
-----END PGP SIGNATURE-----
 
R

Raif S. Naffah

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

Earlier said:
...
the Attack class is defined as:

class Attacker < ActiveRecord::Base
has_many :attacks
has_many :black_listings
end

i meant to write:

class Attack < ActiveRecord::Base
belongs_to :attacker
end


cheers;
rsn
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Que du magnifique

iD8DBQFBpuk2+e1AKnsTRiERA/5xAJ9eB30QYKlb0Pv7i/C3XIARBC6P8ACfc3a9
kP1bi4byzBYUH2PseLeuxBY=
=f2QN
-----END PGP SIGNATURE-----
 
D

David Heinemeier Hansson

at = Attack.find_by_sql(\
"SELECT MIN(occured_on) " +\
"FROM attacks " +\
"WHERE occured_on BETWEEN '#{start_date_str}' AND
'#{end_date_str}'")[0].min

Try using Attact.connection.select_one("SELECT MIN(occured_on)...")

That should return the value without needing to do [0].min. I'm
actually not quite sure why it works on your machine. I would have
thought you needed to do "MIN(occured_on) as min" to get the effect
you're looking for.

But in any case, you should grab the connection like my example above.
It's a slight misuse of AR to load real objects just to get one
aggregated value.
--
David Heinemeier Hansson,
http://www.basecamphq.com/ -- Web-based Project Management
http://www.rubyonrails.org/ -- Web-application framework for Ruby
http://macromates.com/ -- TextMate: Code and markup editor (OS X)
http://www.loudthinking.com/ -- Broadcasting Brain
 
H

Han Holl

at = Attack.find_by_sql(\
"SELECT MIN(occured_on) " +\
"FROM attacks " +\
"WHERE occured_on BETWEEN '#{start_date_str}' AND
'#{end_date_str}'")[0].min

Try using Attact.connection.select_one("SELECT MIN(occured_on)...")

That should return the value without needing to do [0].min. I'm
actually not quite sure why it works on your machine. I would have
thought you needed to do "MIN(occured_on) as min" to get the effect
you're looking for.
Postgresql calls the result fo the min function min by default:

palga=> select min(datont) from main;
min
------------
1990-01-01
(1 row)

Cheers,

Han Holl
 
R

Raif S. Naffah

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

at = Attack.find_by_sql(\
"SELECT MIN(occured_on) " +\
"FROM attacks " +\
"WHERE occured_on BETWEEN '#{start_date_str}' AND
'#{end_date_str}'")[0].min

Try using Attact.connection.select_one("SELECT MIN(occured_on)...")

That should return the value without needing to do [0].min. I'm
actually not quite sure why it works on your machine. I would have
thought you needed to do "MIN(occured_on) as min" to get the effect
you're looking for.

i'll try that and see if it solves the mysql case.

Postgresql calls the result fo the min function min by default:

palga=> select min(datont) from main;
min

indeed; otherwise i would've seen the exception with PostgreSQL, instead
of discovering it with a MySQL setup.

thank you both for your prompt reply. i'll try aliasing the aggregate
function and will get back to you.


also, thank you David for writing such an elegant piece of code, and
making it available, for free.


cheers;
rsn
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Que du magnifique

iD8DBQFBp4hy+e1AKnsTRiERAwmZAJ9vRFku1e8cKG4xtFTWZA8JTzHm9QCg0pzy
MPe5SdYqAbQswBfTpGjM2qE=
=wOk9
-----END PGP SIGNATURE-----
 
R

Raif S. Naffah

-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160

at = Attack.find_by_sql(\
"SELECT MIN(occured_on) " +\
"FROM attacks " +\
"WHERE occured_on BETWEEN '#{start_date_str}' AND
'#{end_date_str}'")[0].min

...I would have
thought you needed to do "MIN(occured_on) as min" to get the effect
you're looking for.

aliasing the aggregate function works with both PostgreSQL and MySQL.


cheers;
rsn
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Que du magnifique

iD8DBQFBrCxM+e1AKnsTRiERA16TAJ92aHqiuXMqJoD6zjszSHw3/WrevACfViOy
aANLW5IuVhM+zNd6fRga3n4=
=nBin
-----END PGP SIGNATURE-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,533
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top