Archive for the 'Development' Category

Git Railed

This is just a little something I threw together this weekend to make life a little easier. git-railed is a simple script that creates a new rails app, initializes a new git repository, moving the db config and setting up the ignores for you. You can use it as a gem, and just run it like:


git-railed obligatory_blog

 

Or, just install it as a sake task, and run it llike:


sake git-railed APP=obligatory_blog

 

Installation notes can be found in the README, get it at github: http://github.com/ambethia/git-railed/tree/master

Please fork it, and customize the behaviors to your hearts content (git-merbed?).

Makes for some ugly SQL, but…


class Listing < ActiveRecord::Base
  belongs_to :book
  belongs_to :guide
 
  def <=>(other)
    self.guide.name <=> other.guide.name
  end
end

Book.find(1).listings.map{ |l| l.guide.name }
# => ["XYZZY", "BAR", "FOO", "QUUX"]

Book.find(1).listings.sort.map{ |l| l.guide.name }
# => ["BAR", "FOO", "QUUX", "XYZZY"]

 

Nice.

MicroTip #1


# Prevent those race conditions in RSpec specs.
@time_now = Time.now
Time.stub!(:now).and_return(@time_now)

 

Exclusive Conditions for ActiveRecord’s has_many

I’ll start with some code.


class User < ActiveRecord::Base
  has_many :things, :exclusive_conditions => %q(`things`.user_id = #{id} OR #{admin?})
end

 

Assuming, we have 2 users, Alice and Bob.


user = User.find_by_username("alice") # => Alice is an admin.
user.id # => 1
thing = user.things.find_by_name("Bob's Thing")
thing.user_id # => 2, It's still bobs thing.

 

Now in my controller’s I can just say something like:


class ThingsController < ApplicationController
  # using restful_authentication or acts_as_authenticated here.
  before_filter :login_required
 
  def update
   @thing = current_user.things.find(params[:id])
   # ...
  end
end

 

Now I don’t have to write any other code to check ownership, AND an admin can
still play with anyone else’s things.

What I’ve done here is added an :exclusive_conditions option to
has_many. It’s not possible to express this idea with the :conditions
option.

Observe:


User.has_many :things, :conditions => ["your_condition = ?", "yes"]

 

Will result in SQL like:


SELECT * FROM things WHERE (user_id = 1) AND (your_condition = ‘yes’)

The “(user_id = 1) AND“ is hard coded. So I can’t say
(user_id = 1) OR (something_else)“ with has_many without writing out
the entire statement using :finder_sql.

But then if I do that, I lose all the fun proxy methods, preventing me from
doing things like user.things.find</tt> or <tt>user.things.create
which are of course, in the scope of that user.

Here’s the plugin, http://subvert.itred.org/has_many_exclusive_conditions/.