ActiveRecord Mixing Conditions + Better Way to Write This

K

Ken Ghosh

Is There A better Way to Write this

I have A Condition which previous Look Very clean and easy to understand
like

Account.first.websites.last.users.find:)all,:conditions => {:country =>
"XYZ",:status => "Single",:admin => nil)

Now the big problem is that user with admin = false is not picked up

i.e i want all the users from a specific country,having status as
"Single" and admin is either "nil"(Null in database) or "false"

I manage to get desired code but doesn't seem to be happy with clarity
of it

Account.first.websites.last.users.find:)all,:conditions => ["country = ?
AND status = ? AND admin IS NULL OR admin = ?","XYZ","Single","false"])

Any Help would be appreciated

thanks
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

Is There A better Way to Write this

I have A Condition which previous Look Very clean and easy to understand
like

Account.first.websites.last.users.find:)all,:conditions => {:country =>
"XYZ",:status => "Single",:admin => nil)

Now the big problem is that user with admin = false is not picked up

i.e i want all the users from a specific country,having status as
"Single" and admin is either "nil"(Null in database) or "false"

I manage to get desired code but doesn't seem to be happy with clarity
of it

Account.first.websites.last.users.find:)all,:conditions => ["country = ?
AND status = ? AND admin IS NULL OR admin = ?","XYZ","Single","false"])

Any Help would be appreciated

thanks
Hi, this is a Ruby list, so it would be best to ask questions like this on a
Rails list (looks like you're posting from ruby-forum.com, you can access
the Rails list from there too http://www.ruby-forum.com/forum/3)


At http://apidock.com/rails/ActiveRecord/Base/find/class they suggest doing

Project.all <http://apidock.com/rails/ActiveRecord/Base/all/class>:)conditions
=> "archived IS NULL OR archived = 'f'")


Which is pretty similar to what you're trying to do, but its biggest
shortcoming is that it doesn't play well with other conditions. At one time
I swore you could chain these together, but now they seem to return an Array
instead of a lazy object (maybe I was thinking of DataMapper?) Anyway, to
get around that issue, you can make it a named scope like this

class User < ActiveRecord::Base
named_scope :not_admin , lambda {{ :conditions => "admin IS NULL OR admin
= 'f'" }}
end

This creates a method User.not_admin that will start building a query (and
execute it if you call just like this) you can then append to that query
your other conditions. The lambda is just like a do ... end block, except
that it returns a reference to the object it creates, you can think of it
exactly like a do end block, but you need to use curly braces on it because
of how blocks bind of objects. So the first curly braces are for the block,
the second are for the hash table we are returning.

This then lets you make queries like so:
User.not_admin
User.not_admin.all( :conditions => { :country =>"XYZ" , :status => "Single"
} )


As an alternative, you might set admin to be false by default (your
migration would look like t.boolean :admin , :default => false ), and then
validate that it is either true or false (in your class add
validates_inclusion_of :admin, :in => [true, false]) Then you don't have to
deal with having two kinds of falses. Note that this will prevent the record
from saving if it gets set to nil (it will default to false, though, so this
can only happen if something explicitly sets it to nil).
 
B

Brian Candler

Ken said:
I manage to get desired code but doesn't seem to be happy with clarity
of it

Account.first.websites.last.users.find:)all,:conditions => ["country = ?
AND status = ? AND admin IS NULL OR admin = ?","XYZ","Single","false"])

Beware relative precedence of AND and OR. It's possible AND binds more
tightly than OR, I'm not sure. So to be safe:

["country = ? AND status = ? AND (admin IS NULL or admin=?)", ...]

If you are using Rails 3, then look at the new syntax which Active
Relation gives you. Google "rails 3 arel"
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top