Photo-1 Photo-2 Photo-3 Photo-4 Photo-5 Photo-6

@brentmc79

@brentmc79

Full-time web developer. Part-time smart ass.

I'm Brent Collier.

After a year and a half as an engineer on Twitter's Trust & Safety team, I'm looking for my next gig. Contact me if you know of something interesting.

#

Override an AR default_scope

Posted on 06/08/2011

Say you've got a Thing class and your app uses soft deletes, so maybe you've got a default scope like so

default_scope where(:active => true)

and you want to find Thing records that have been (soft)deleted, so you try this

Thing.where(:active => false).all

which returns this

[]   #sadface

What gives?

Well, your default scope hold precedence over your where condition, so what you need to do is this

Thing.unscoped.where(:active => false).all

Using the unscoped scope returns an AR::Relation without the default scope, allowing you query for whatever you want. Enjoy.


Update

Or, as it turns out, you can create a scope that negates the default scope, like so

class Thing
  default_scope where(:active => true)
  scope :inactive, where(:active => false)
end
#

Order by Associated Model Count

Posted on 04/26/2011

Say you've got an Author model, and that model has_many :books. Here's how to retrieve the list of models, order by the number of books they've each authored:

Author.joins(:books).select("authors.*, count(books.id) as books_count").order("books_count DESC").group("authors.id")

Note that if you don't include the group condition that it return an Author record for each book. So if an author has written four books, then that author will appear four times in the resulting array.

#

Archive links, quick and easy

Posted on 04/14/2009

So I finally got around to replacing the dummy text in the sidebar with real, working archive links, and it was stupidly easy.  Check it out...

First, I added a helper method to take all published posts and group them by the month they were created.

def archives
  @archives = Post.published.in_order.all.group_by { |t| t.created_at.beginning_of_month}
end

Then I used that helper method to display links for each month in which posts were created.

<ul>
  <% archives.each do |month, posts| %>
    <li><%= link_to(month.strftime('%B')+" (#{posts.size})", archive_path(:month => month.month, :year => month.year)) %></li>
  <% end %>
</ul>

You probably noticed the archive_path named route that the links point to. Here's how I set it up.

map.archive '/posts/:year/:month', :controller => 'posts', :action => 'archive'

That route points to the archive action of the posts controller which merely retrieves the posts created within the specified month and renders the list view.

def archive
  @posts = Post.published.in_order.from_month(Time.parse "#{params[:month]}/#{params[:year]}").paginate(:page => params[:page], :per_page => 5)
  render :action => 'index'
end

The archive action uses a from_month named scope on the Post model to restrict the find to all posts created within a given month.

named_scope :from_month, lambda { |month| {:conditions => {:created_at => month..(month + 1.month)}} }

That's it. That's all it takes to set up simple archive links for your blog.