Posted by Randy
on March 13, 2009
While you can achieve the same functionality using sprintf, this may provide a cleaner approach and one that you are more familiar with. This will allow you to build a string the same way you can use ActiveRecord and the :conditions option.
Basically how this works is by overriding the Array class and adding a method to merge the string and values together into unified string! Enough talk, lets see some code:
class Array
def merge
statement, *values = self
expected = statement.count("?")
provided = values.size
raise "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}" unless expected.eql?(provided)
bound = values.dup
statement.gsub("?") { bound.shift }
end
end
As you can see, if you do not provide the right number of values for the statement, it will raise and error. Here is how you would use it:
puts ['Hello ?, how are you', 'John'].merge
#=> Hello John, how are you
Likewise, you can use variables to hold values:
message = "Hello ?, how are you"
name = 'John'
puts [message, name].merge
#=> Hello John, how are you
This will also work with multiple values:
puts ['Hello ?, ? and ?, how are you', 'John', 'Joe', 'Jim'].merge
#=> Hello John, Joe, and Jim, how are you
The only downside to this currently is that you cannot use a ? in the string you are merging, as it will think its a binding character.
Posted by Randy
on August 29, 2008
I’m sure you all know how to use the :conditions attribute when using ActiveRecord:
User.find(:all, :conditions=>['active = ?', true])
And you may even use associations this way:
User.find(:all, :include=>[:photos], :conditions=>['photos.removed = ? and users.active = ?', false, true])
But did you know that you can do this easier through hashes?
User.find(:all, :conditions=>{:active=>true})
User.find(:all, :include=>[:photos], :conditions=>{'photos.removed'=>false, 'users.active'=>true})
Nothing special there, but I thought it was pretty cool. One thing you have to remember when using associations, is to include that model.
Posted by Randy
on May 14, 2008
Here is a little trick I use when I want to override a find method for a model, instead of adding the conditions option to my association. While I don’t think you should avoid using the conditions options in your associations, this will provide an alternative:
class ModelName < ActiveRecord::Base
def self.find(*args)
with_scope(:find=>{ :conditions=>LIMIT_CONDITION }) do
super(*args)
end
end
end
Basically what is happening, is that you are overriding the default find function for a model, and wrapping its own find method with a with_scope call. So now everytime you call Model.find(:all) or whatever options you want, it will execute it under that scope, with the conditions you specify.