squeel

Upload: gteodorescu

Post on 04-Jun-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/13/2019 Squeel

    1/9

    Squeel

    Squeel lets you write your Active Record queries with fewer strings, and more Ruby, by

    making the Arel awesomeness that lies beneath Active Record more accessible.

    Squeel lets you rewrite...

    Article.where ['created_at >= ?', 2.weeks.ago]

    ...as...

    Article.where{created_at >= 2.weeks.ago}

    This is agood thing. If you don't agree, Squeel might not be for you. The above is ust a

    sim!le e"am!le ## Squeel's ca!able of a whole lot more. $ee! reading.

    Getting started

    In your %emfile&

    gem "sqeel" ! ast o##iciall$ released gem! gem "sqeel", %git => "git%&&gith.com&er(ie&sqeel.git" ! )rack gitre*o

    Then bundle as usual.

    If you'd like to customie Squeel's functionality by enabling core e"tensions for hashes orsymbols, or aliasing some !redicates, you can create a sam!le initialier with&

    + rails g sqeel%i(itialier

    The Squeel Query DSL

    Squeel enhances the normal Active Record query methods by enabling them to acce!t blocks.

    Inside a block, the Squeel query (S) can be used. *ote the use of curly braces in these

    e"am!les instead of !arentheses. {}denotes a Squeel (S) query.

    Stubs and key!aths are the two !rimary building blocks used in a Squeel (S) query, so we'llstart by taking a look at them. +ost of the other e"am!les that follow will be based on this

    symbol#less block synta".

    An important gotcha, before we begin:The Squeel (S) works its magic using

    i(sta(ce_e-al. If you've been working with Ruby for a while, you'll know immediately that

    this means that insidea Squeel (S) block, sel#isn't the same thing that it is outsidethe

    block.

    This carries with it an im!ortant im!lication& Instance variables and instance methods

    inside the block won't refer to your object's variablesmethods!

  • 8/13/2019 Squeel

    2/9

  • 8/13/2019 Squeel

    3/9

    All of the Arel !redication methods can be accessed inside the Squeel (S), via their

    method name, an alias, or an an o!erator, to create Arel !redicates, which are used in 9:1

    or :ABCclauses.

    S"# $redication %perator Alias

    8 eq 88

    98 not:eq 98 1.; only2, < 1.=2

    )I$> matches 87 like

    *?T )I$> does:not:match 97 1.; only2 not:like

    @ lt @

    @8 lteq @8 lte

    gt

    8 gteq 8 gte

    I* in

    *?T I* not:in @@

    )et's say we want to generate this sim!le query&

    34) "*eo*le".5 6178 *eo*le 9:1 "*eo*le"."(ame" = '@oe Dlow'

    All of the following will generate the above SB)&

    erso(.where '@oe Dlow'erso(.where{{(ame => '@oe Dlow'}}erso(.where{{(ame.eq => '@oe Dlow'}}erso(.where{(ame.eq '@oe Dlow'}

    erso(.where{(ame == '@oe Dlow'}

    *ot a very e"citing e"am!le since equality is handled ust fine via the first e"am!le in

    standard Active Record. Cut consider the following query&

    34) "*eo*le".5 6178 *eo*le9:1

  • 8/13/2019 Squeel

    4/9

    . To read code with SB) inter!olation, the structure of the SB) query must first be

    considered, then we must cross#reference the values to be substituted with their

    !laceholders. This carries with it a small but !erce!tible 1and annoying92 conte"t shift

    during which we sto! thinking about the com!arison being !erformed, and instead

    !lay count the arguments, or, in the case of namedDhash inter!olations, find the

    word. The Squeel synta" !laces both sides of each com!arison in !ro"imity to oneanother, allowing us to focus on what our code is doing.

    /. In the first e"am!le, we're starting off with Ruby, switching conte"t to SB), and then

    back to Ruby, and while we s!end time in SB)#land, we're stuck with SB) synta",

    whether or not it's the best way to e"!ress what we're trying to do. 4ith Squeel, we're

    writing Ruby from start to finish. And with Ruby synta" comes fle"ibility to e"!ress

    the query in the way we see fit.

    Predicate aliases

    That last bit is im!ortant. 4e can mi" and match !redicate methods with o!erators and take

    advantage of Ruby's o!erator !recedence or !arenthetical grou!ing to make our intentions

    more clear, on the first read#through. And if we don't like the way that the e"isting

    !redications read, we can create our own aliases in a Squeel configure block&

    3qeel.co(#igre do /co(#ig/ co(#ig.alias_*redicate %is_less_tha(, %lte(derso(.where{salar$.is_less_tha( IJJJJ}.to_sql! => 34) "*eo*le".5 6178 "*eo*le" 9:1 "*eo*le"."salar$" H IJJJJ

    And while we're on the to!ic of hel!ing you make your code more e"!ressive...

    Compound conditions

    )et's say you want to check if a Eerson has a name like one of several !ossibilities.

    (ames = ['r(ieF', '@oeF', '8ar$F']erso(.where 34) "*eo*le".5 6178 "*eo*le"! 9:1

  • 8/13/2019 Squeel

    5/9

    Sifters

    Sifters are like little sni!!ets of conditions that take !arameters. )et's say that you have a

    model called Article, and you often want to query for articles that contain a string in the title

    or body. So you write a sco!e&

    de# sel#.title_or_od$_co(tai(s

  • 8/13/2019 Squeel

    6/9

    ! 9:1 "articles"."athor_id" 34) "*eo*le".5 6178 "*eo*le"! 6) 7M)1 @7 "articles" 7 "articles"."*erso(_id" = "*eo*le"."id"ote.;oi(s{(otale 34) "(otes".5 6178 "(otes"! 6) 7M)1 @7 "*eo*le"! 7 "*eo*le"."id" = "(otes"."(otale_id"! AG "(otes"."(otale_t$*e" = 'erso('

    These can also be used inside key!aths&

    ote.;oi(s{(otale 34) "(otes".5 6178 "(otes"! 1 @7 "*eo*le" 7 "*eo*le"."id" = "(otes"."(otale_id"! AG "(otes"."(otale_t$*e" = 'erso('! 1 @7 "articles" 7 "articles"."*erso(_id" = "*eo*le"."id"

    0ou can refer to these associations when constructing other !arts of your query, and they'll be

    automatically ma!!ed to the !ro!er table or table alias This is most noticeable when using

    self#referential associations&

    erso(.;oi(s{childre(.*are(t.childre(}. where{

  • 8/13/2019 Squeel

    7/9

    ...and you can easily give it an alias&

    *erso( = erso(.select{ coalesce'.as "Aric 3mithQdiddl$"*.(ame_with_de#alt! => "Aric 3mith"

    Compatibility with Active Record

    +ost of the new functionality !rovided by Squeel is accessed with the new block#style

    where{}synta".

  • 8/13/2019 Squeel

    8/9

    All your e"isting code that uses !lain Active Record where

  • 8/13/2019 Squeel

    9/9

    erso(.;oi(s %comme(ts. where {%comme(ts => {%od$.matches => ':elloR'}}! => 34) "*eo*le".5 6178 "*eo*le"! 1 @7 "articles" 7 "articles"."*erso(_id" = "*eo*le"."id"! 1 @7 "comme(ts" 7 "comme(ts"."article_id" = "articles"."id"! 9:1 "comme(ts"."od$" E ':elloR'

    This should hel! to smooth over the transition to the new (S).

    Contributions

    If you'd like to su!!ort the continued develo!ment of Squeel, !lease consider making a

    donation.

    To su!!ort the !roect in other ways&

    -se Squeel in your a!!s, and let me know if you encounter anything that's broken or

    missing. A failing s!ec is awesome. A !ull request is even better9

    S!read the word on Twitter, 6acebook, and elsewhere if Squeel's been useful to you.

    The more !eo!le who are using the !roect, the quicker we can find and fi" bugs9

    Copyright

    Jo!yright K /L >rnie +iller

    https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N7QP5N3UB76MEhttps://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N7QP5N3UB76MEhttp://twitter.com/erniemillerhttps://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N7QP5N3UB76MEhttps://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=N7QP5N3UB76MEhttp://twitter.com/erniemiller