ActiveRecord Mixing Conditions + Better Way to Write This

Discussion in 'Ruby' started by Ken Ghosh, Sep 29, 2010.

  1. Ken Ghosh

    Ken Ghosh Guest

    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
    --
    Posted via http://www.ruby-forum.com/.
    Ken Ghosh, Sep 29, 2010
    #1
    1. Advertising

  2. Ken Ghosh

    Josh Cheek Guest

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

    On Wed, Sep 29, 2010 at 4:25 AM, Ken Ghosh <> wrote:

    > 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
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >

    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).
    Josh Cheek, Sep 29, 2010
    #2
    1. Advertising

  3. Ken Ghosh wrote:
    > 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"
    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, Sep 29, 2010
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Martin Buchleitner
    Replies:
    6
    Views:
    27,723
    Moody
    Jul 17, 2003
  2. A
    Replies:
    15
    Views:
    437
    James Kanze
    Oct 5, 2010
  3. Adam Boyle
    Replies:
    7
    Views:
    166
  4. dkmd_nielsen
    Replies:
    1
    Views:
    108
    dkmd_nielsen
    Oct 31, 2008
  5. Replies:
    2
    Views:
    44
    Mark H Harris
    May 13, 2014
Loading...

Share This Page