<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1413889227948810609</id><updated>2011-04-21T23:03:10.913-05:00</updated><category term='ruby'/><category term='plugin'/><category term='rails'/><title type='text'>X Andrews</title><subtitle type='html'>A former non-blogger blogs. Infrequently.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://xandrews.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1413889227948810609/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://xandrews.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>John Andrews</name><uri>http://www.blogger.com/profile/10059332884446781170</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1413889227948810609.post-8398241552704912448</id><published>2007-02-15T20:27:00.000-05:00</published><updated>2007-02-15T20:57:03.238-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>More on scope_out</title><content type='html'>&lt;a href="http://dcmanges.com"&gt;Dan Manges&lt;/a&gt;, one of my coworkers, wrote an &lt;a href="http://dcmanges.com/blog/21"&gt;excellent post&lt;/a&gt; on some of the reasons why you would want to use the scope_out plugin. You should go read it because he does a much better job of explaining it than I would. I just wanted to take this opportunity to point out some of the newer features that weren't included in the first release.&lt;br /&gt;&lt;br /&gt;Dynamic conditions are now accepted if you pass a block to scope out. Notice how the block evaluates to a Hash. This is important because the block is evaluated each time the scope is called and the result is fed directly to Rails' with_scope method as the options parameter.&lt;br /&gt;&lt;pre style="overflow:auto"&gt;&lt;br /&gt;  class Article &lt; ActiveRecord::Base&lt;br /&gt;    scope_out :published_today do&lt;br /&gt;      {:conditions =&gt; {:publish_date =&gt; Date.today}}&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can combine scopes with a new method called (predictably) combined_scope. This method takes previously defined scopes which were created with scope_out and nests them in order to create a new scope.&lt;br /&gt;&lt;pre style="overflow:auto"&gt;&lt;br /&gt;  class Person &lt; ActiveRecord::Base&lt;br /&gt;    scope_out :software_developers, :conditions =&gt; {:job =&gt; "Software Developer"}&lt;br /&gt;    scope_out :ruby_programmers, :conditions =&gt; {:primary_language =&gt; "Ruby"}&lt;br /&gt;    combined_scope :happy_programmers, [:software_developers, :ruby_programmers]&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1413889227948810609-8398241552704912448?l=xandrews.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xandrews.blogspot.com/feeds/8398241552704912448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1413889227948810609&amp;postID=8398241552704912448' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1413889227948810609/posts/default/8398241552704912448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1413889227948810609/posts/default/8398241552704912448'/><link rel='alternate' type='text/html' href='http://xandrews.blogspot.com/2007/02/more-on-scopeout.html' title='More on scope_out'/><author><name>John Andrews</name><uri>http://www.blogger.com/profile/10059332884446781170</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1413889227948810609.post-4826175435024645922</id><published>2007-01-13T16:22:00.000-05:00</published><updated>2007-02-15T23:34:25.450-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>XOR</title><content type='html'>While making my &lt;a href="http://xandrews.blogspot.com/2007/01/scopeout-your-models.html"&gt;scope_out&lt;/a&gt; plugin, I wanted to ensure that exactly one of the 2 possible hash keys (:value or :conditions) were passed to the method. Rather than using a long and ugly if statement, I wanted to use the &lt;span style="font-style:italic;"&gt;xor&lt;/span&gt; operator (^). Unfortunately ^ is not a regular boolean operator and is not defined for strings or arrays which can be passed as values to my hash. So I came up with this as a workaround:&lt;br /&gt;&lt;pre style="overflow:auto"&gt;&lt;br /&gt;if (options[:value] &amp;&amp; true) ^ (options[:conditions] &amp;&amp; true)&lt;br /&gt;  #do stuff&lt;br /&gt;else&lt;br /&gt;  raise "use either :value or :conditions, but not both"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The return value of an &lt;span style="font-style:italic;"&gt;and&lt;/span&gt; expression is the right hand side of that expression if the left part is true. Therefore the hash values are both coerced into either boolean or nil types, both of which define the ^ method.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt;&lt;br /&gt;Since publishing the plugin I realized that there are reasons where you would want to pass nil or false to options[:value] so I have changed the code to the following:&lt;br /&gt;&lt;pre style="overflow:auto"&gt;&lt;br /&gt;if (options.has_key?(:value) ^ options.has_key?(:conditions)&lt;br /&gt;  #do stuff&lt;br /&gt;else&lt;br /&gt;  raise "use either :value or :conditions, but not both"&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1413889227948810609-4826175435024645922?l=xandrews.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xandrews.blogspot.com/feeds/4826175435024645922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1413889227948810609&amp;postID=4826175435024645922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1413889227948810609/posts/default/4826175435024645922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1413889227948810609/posts/default/4826175435024645922'/><link rel='alternate' type='text/html' href='http://xandrews.blogspot.com/2007/01/xor.html' title='XOR'/><author><name>John Andrews</name><uri>http://www.blogger.com/profile/10059332884446781170</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1413889227948810609.post-6573356887029830760</id><published>2007-01-13T10:37:00.000-05:00</published><updated>2007-01-13T17:04:33.377-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>scope_out your models</title><content type='html'>After reading &lt;a href="http://errtheblog.com/post/41"&gt;this excellent post on with_scope&lt;/a&gt;, I started using the with_x, find_x pattern all over the place. As a first step toward becoming a real contributing member of the rails community, I took the time to turn the pattern into a Rails plugin. And so &lt;a href="http://code.google.com/p/scope-out-rails"&gt;scope_out&lt;/a&gt; was born.&lt;br /&gt;&lt;br /&gt;Briefly, you would use scope_out like so:&lt;br /&gt;&lt;pre style='overflow:auto'&gt;class Thing &lt; ActiveRecord::Base&lt;br /&gt;  scope_out :active, value =&gt; true&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This simple declaration defines three class methods for you, like so: &lt;br /&gt;&lt;pre style='overflow:auto'&gt;&lt;br /&gt;def Thing.with_active&lt;br /&gt;  with_scope :find =&gt; {:conditions =&gt; ['active =&gt; ?', true]} do&lt;br /&gt;    yield&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;def Thing.find_active(*args)&lt;br /&gt;  with_active {find(*args)}&lt;br /&gt;end&lt;br /&gt;def Thing.calculate_active(*args)&lt;br /&gt;  with_active {calculate(*args)}&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;There are 2 basic syntaxes for using scope_out. In the first, you may omit :field if the name of the field is the same as the name of the scope. :value can be a boolean, integer, or string. :conditions can take any of rails' normal condition syntaxes.&lt;br /&gt;&lt;pre style='overflow:auto'&gt;&lt;br /&gt;scope_out(:scope_name, :field =&gt; 'field_name', :value =&gt; value)&lt;br /&gt;scope_out(:scope_name, :conditions =&gt; ['field =&gt; ?', value])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So there you have it, pure syntactic sugar. 100% meta. Enjoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1413889227948810609-6573356887029830760?l=xandrews.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xandrews.blogspot.com/feeds/6573356887029830760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1413889227948810609&amp;postID=6573356887029830760' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1413889227948810609/posts/default/6573356887029830760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1413889227948810609/posts/default/6573356887029830760'/><link rel='alternate' type='text/html' href='http://xandrews.blogspot.com/2007/01/scopeout-your-models.html' title='scope_out your models'/><author><name>John Andrews</name><uri>http://www.blogger.com/profile/10059332884446781170</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
