star symbol in front of Ruby def argument

you may have seen something like this and wondered what the star symbol inside the argument parenthesis was:

def some_method(*args)
  #cowboy code goes here
end

The star symbol in front of args means that this method can accept an unlimited number of arguments. This is commonly used in Ruby on Rails when extracting options from the method arguments:

options = args.extract_options!

extract_options! is an ActiveSupport method that pulls out the option hashes from the method arguments.

Ruby – cattr_accessor vs attr_accessor

What is the difference in these two. You see attr_accessor alot more than cattr_accessor. I actually just stumbled upon it while trying to understand the ActiveRecord code.

Apparently, cattr_accessor is class level equivalent of attr_accessor. So cattr_accessor operates at the class level, while attr_accessor operates at the instance level.

Here is an example using a Counter class:

class Counter
  cattr_accessor :class_count
  attr_accessor :instance_count
end

counter1 = Counter.new
counter1.instance_count = 1
counter1.class_count = 1

counter2 = Counter.new
p counter2.instance_count
#> nil
p counter2.class_count
#> 1

As you can see the cattr_accessor stays the same for every instance, while the attr_accessor is only on the instance of the class.

Behind the scenes it is just using class and instance variables for the getter/setter methods
@@class_count
@instance_count

Ruby on Rails dynamic finder – find_or_create method

Here is another one I was not aware of. I knew you could use dynamic finders to look for one or more attributes, but I did not realize you could do a find and create at the same time (well.. not really both of them at once, but you know what I mean)

Blog.find_or_create_by_title(“Some Blog”)

If there is a blog with title = “Some Blog”, then it will pull this blog out of the table. If the blog does not exist, a new Blog is created with the title “Some Blog”. Alternately you can use find_or_initialize_by_name and it will not save the object to the database immediately.. it will be available in the scope of your code, just as if you called blog = Blog.new(:title=>”Some Blog”)

This could come in handy in certain situations and save you a line of code. Daddy like

Overriding Rails ActiveRecord object getter/setter fields

Lets say you have a widget model in Ruby on Rails.  Your database table contains a field called “name”.  Let’s say you want to add something to this field in your model.  You need a specialized def in order to do this.. you need to use write_attribute and read_attribute methods.

Here is an example where I override the Rails ActiveRecord model attribute setter. This will append a test string onto the name:

class Widget < ActiveRecord::Base
  def name=(name)
    write_attribute(:name,"#{name} - test")
  end
end

You can also do this with the read_attribute method and it works the opposite way… instead of operating on the setter, you operate on the getter.

SQL IN – Do it in Rails find using an array

I thought this was pretty cool and a little more elegant than using a string, which I have been doing before I saw this. In SQL you can do a command like so:

SELECT * FROM widgets WHERE id IN (1,2,3,4,5);

I was doing this before:

Widget.find(:all,:conditions=>”id in (1,2,3,4,5)”)

Instead of doing this you can use an array instead of a string:

Widget.find(:all,:conditions=> {:id => [1,2,3,4,5])

That looks better.

Ruby programming – what is dollar sign colon .unshift ($:.unshift) ??

This is a special variable in ruby. Ruby special variables start with the dollar sign followed by a single character. This particular variable is the default search path for load or require. If you call it in irb or the rails console, you can see it returns an array of strings which are paths.

Since it returns an array, the unshift is simply an array method that adds an object to the beginning of an array.

An example of this can be seen in the ActiveRecord source (2.3.2 rails). In this particular example, the ActiveSupport path is prepended to the array, so that it can be required in the code.

activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
if File.directory?(activesupport_path)
  $:.unshift activesupport_path
  require 'active_support'
end

There are a bunch of other special variables in ruby like this one. Take a look here for more info: http://www.zenspider.com/Languages/Ruby/QuickRef.html#18

MySQL group by day, month or year using a timestamp column

In Ruby on Rails, created_at and updated_at columns are MySQL timestamp columns.  GROUP BY is pretty useless on a timestamp column, unless you are trying to group rows that were added at the same second.  I needed to group by just the date, so in order to do this I had to manipulate the timestamp with a MySQL operator.  Using the DATE_FORMAT operator, you can easily group the timestamp column using any format you want.  For my example, I needed to group rows that were added on the same day.  Here is my query:

select count(*), DATE_FORMAT(created_at,”%Y-%m-%d”) as created_day FROM widgets GROUP BY created_day

This query will give you something like this:

count(*) | created_day
126 | 2010-04-12
168 | 2010-04-13
169 | 2010-04-14
189 | 2010-04-15
187 | 2010-04-16
13 | 2010-04-17

Ruby If statements – all objects are true, except FalseClass (false)

This was a bit confusing to me since I was used to programming in other languages. Basically every object has a boolean value with is true, unless the object is false or nil. Even the integer 0 will return true if you put it into an “if” expression. Take a look at some examples:

# STRING TEST
if "test"
  p "true"
else
  p "false"
end
=>"true"

#FIXNUM TEST
if 0
  p "true"
else
  p "false"
end
=>"true"

#FalseClass TEST
if false
  p "true"
else
  p "false"
end
=>"false"

#NIL TEST
if nil
  p "true"
else
  p "false"
end
=>"false"

I find this logic especially useful when passing an options hash inside a function. It allows you to use an if expression on the option and it will always return true, unless that object is nil or has been set to false. This allows you to test if an option exists by writing only:

if option[:some_option]
  # do something
end

Anyways.. I just thought that was a pretty cool feature, compared to other languages

Ruport error – undefined local variable or method `acts_as_reportable’

I was trying to install ruport by reading some of the sparse tutorials on the web.  It took some trial and error to actually get ActiveRecord to recognize the acts_as_reportable call.  Some of the documentation just said installing ruport was enough, but in my scenario I found that you also have to install acts_as_reportable as a seperate gem. Maybe Ruport is not including that in the lateset version?? I am nots ure.. didn’t really look at the latest commits to the code.

Here is what I had to do:
1. gem install ruport
2. gem install acts_as_reportable
3. put this in your environment.rb inside the initializer

Rails::Initializer.run do |config|
  ...
  require "ruport"
  require "ruport/acts_as_reportable"
  ...
end

That should do the trick and Rails will recognize acts_as_reportable.

UPDATE: After a closer look at the documentation, this was already metioned -> http://ruportbook.com/acts_as_reportable.html
Thanks Andrew!

Testing email with sendmail using the command line

This is pretty easy to do.  First create a file with your subject and body in it.  I will call it email.test

Subject: Testing some email
this is my message
<blank line>

of course you dont actually write <blank line>.  Just hit enter/return after the message body, so it adds a blank line.

Then you send the email using this command.  The -v option makes it verbose, so you can see whats going on.

>/usr/sbin/sendmail -v my@address.com < email.test

Note: your sendmail executable might be located somewhere other than /usr/sbin/sendmail. Its most likely in a /bin or /sbin directory. You can search for it using:

find / -name sendmail