Forum: Ruby on Rails :all or noop operator for find_all_by_*?

Posted by Felix Schäfer (Guest)
on 2009-07-03 21:38
(Received via mailing list)
Hello,

I've been looking for a way to noop a find_all_by. Use case: I have a
function that takes a hash called options as argument, and that
operates on a subset of Host objects as such:
"""
client_id = options[:client] ? Client.find(options[:client]) : nil
old_hosts = client_id ?
Host
.last_seen_before
(minutes.minutes.ago).find_all_by_client_id(client_id) :
Host.last_seen_before(minutes.minutes.ago)
"""
last_seen_before is a named_scope. If I had a noop for the
find_all_by_client_id, I could make due of the client_id ? : part in
the second line.

I admit that this is quite a simple a case, and that it doesn't add
much complexity to the program, but I'll soon have to add some more
filters and/or scopes, and I'd hate to make different calls depending
on whether the option is set or not.

Does anyone know a way to make this less painfull?

Thanks,

Felix
Posted by Marnen Laibow-Koser (marnen)
on 2009-07-03 22:47
Felix Schäfer wrote:
> Hello,
> 
> I've been looking for a way to noop a find_all_by.
[...]
> Does anyone know a way to make this less painfull?

Hackish, but...

if client_id.nil?
  finder = :or
else
  finder = :find_all_by_client_id
end

Host.last_seen_before.send(finder, client_id)

> 
> Thanks,
> 
> Felix

Best,
--
Marnen Laibow-Koser
http://www.marnen.org
marnen@marnen.org
Posted by Matt Jones (Guest)
on 2009-07-04 19:44
(Received via mailing list)
Assuming that Client has_many Hosts, you could do:

client_hosts = options[:client] ? Client.find(options
[:client]).hosts : Host
old_hosts = client_hosts.last_seen_before((minutes.minutes.ago)

--Matt Jones
Posted by Felix Schäfer (Guest)
on 2009-07-04 20:43
(Received via mailing list)
Am 04.07.2009 um 19:11 schrieb Matt Jones:

> Assuming that Client has_many Hosts, you could do:

Yes, it has.

> client_hosts = options[:client] ? Client.find(options
> [:client]).hosts : Host
> old_hosts = client_hosts.last_seen_before((minutes.minutes.ago)


That still leaves me with a ? : construct, which in my eyes should be
useless.

Anyway, thanks Marnen and Matt for the suggestions, but I've gone with
the scope chaining mentioned in another post a little earlier on the
list. For the record, the result is:
"""
minutes   = options[:minutes] || 10
client_id = options[:client] ? Client.find(options[:client]) : nil

old_hosts = Host.last_seen_before(minutes.to_i.minutes.ago)
old_hosts = old_hosts.find_all_by_client_id(client_id) unless
client_id.nil?
"""

For the next options/scopes, I can just continue to do 'old_hosts =
old_hosts.other_scope(some_param) unless some_param.nil?' to further
chain the scopes and thus narrow the list of results as needed.

Regards,

Felix
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.