ActiveRecord conditions with association from hash

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.

Custom Rails Environments

Sometimes you need to create another environment for your rails application aside from development, test, production. In this example we will create a “stage” environment. Here is how you do it. First create the entry in your config/database.yml file:

# Stage database configuration
stage:
  adapter: sqlite3
  database: db/stage.sqlite3
  timeout: 5000

Next create a file called stage.rb and place it into config/environments. I usually just copy my development.rb file and then change the values as needed: Finally, In your config/environment.rb file, change the ENV[‘RAILS_ENV’] to:

ENV['RAILS_ENV'] ||= 'stage'

Now when you boot up your server or console, just specify the “stage” environment.

session[:current_user] = @user => BAD!

I’m sure most of you already would know this, or use restful authentication that handles it for you. However, if you have some custom setup where you are loading a user object, and then storing it in session, slap to you! Basically what I am talking about is doing this in your login method:

session[:current_user] = @user

Instead you should do:

session[:current_user] = @user.id

And then in your application controller, setup a before filter like so:

def set_current_user
  @current_user = User.find(session[:current_user])
end

One main reason not to do that would be if you had to update some user information. If you had it stored in session, then the user would have to log out and log back in for the changes to take effect. This is of course a basic rough draft, but you get the idea.

Rails Security – SQL Injection – Sanitize User Input!

Even though rails makes every effort to help with security in your apps, you should still be proactive about it. Don’t just assume that your data will be safe no matter how you code. Here is a prime example. You have a login form and you process the request like this:

user = User.find(:first, :conditions=>["login = '#{params[:login]}'"])

You just essentially told every hacker to kill your data by doing something like “‘; delete from users;–“, or even worse a database drop. The appropriate way would be like this:

user = User.find(:first, :conditions=>['login = ?', params[:login]])

Other things you want to make sure you do is to sanitize your views as well:

<%= h @model.value %>

Assume the worse and check all your user input to make sure they can’t do anything you don’t want them to and you will have a happy APP!

Capistrano, CVS, and connection refused issue

If you ever find yourself using CVS as your repository, and are trying to deploy your projects via capistrano, you may run into a connection refused issue. The easiest way I found a solution around this was to modify the capistrano file: “/capistrano-2.1.0/lib/capistrano/recipes/deploy/scm/cvs.rb”. This of course is in your ruby gems folder.I could have added just the change to my project, but I am lazy, and need this for multiple CVS project deploying from this machine. The change I made was on line 145, which I added the CVS_RSH=ssh line:

"export CVS_RSH=ssh && mkdir -p #{ dest } && cd #{ dest }"