How to get better error messages for an associated model.
Hey there. Let's assume you have some set like this
class User < ActiveRecord::Base
  has_one :profile , :dependent => :destroy
end


class Profile < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :first_name, :last_name
end

And you create the profile in the same view as your user. How do you validate those first_name and last_name fields with a friendly message for your user?
Well, you could use validates_associated, but you would end up with a message like "Profile is invalid". Now, how friendly is that?

To obtain a more precise message, use this on you user.rb

def validate
  if self.profile
    self.profile.errors.each do |error|
      self.errors.add_to_base error.join(' ')
    end
  end
end
Difference between is_a? and instance_of?

Hi Sirs.

There is a difference between a bunch of methods that appear that they to the same job, but they won't.

The methods instance_of?, is_a? and kind_of? do related jobs, but not the same job.

For example is_a? and kind_of? do the same job, they return true if the caller is an instance of the method argument, if the caller is an instance of every superclass in his inheritance tree or if the argument method is a module included in the caller.

The instance_of? is more specific, it returns true just if the caller is an instance of the method argument.

Let me show some examples:

module Hand
end

class Animal
end

class Mamal < Animal
  include Hand
end

class Dog < Mamal
end

dog = Dog.new

puts dog.instance_of?(Dog)    # true
puts dog.instance_of?(Mamal)  # false
puts dog.instance_of?(Animal) # false
puts dog.instance_of?(Hand)   # false

puts dog.is_a?(Dog)    # true
puts dog.is_a?(Mamal)  # true
puts dog.is_a?(Animal) # true
puts dog.is_a?(Hand)   # true 

Remember that is_a? and kind_of? do the same job.

See you.

Diff entre respond_to? e respond_to

Um pequeno tutorial em português pra diferenciar melhor respond_to? e respond_to. Não parece ter muita não? Mas o tio Chuck Norris vai me ajudar a esclarecer melhor isso aqui.

respond_to? é um método do Ruby Core como você pode ver, e não do Ruby On Rails, ele basicamente verifica se determinado objeto responde a um método, como o nome sugere mesmo.

Por exemplo:

class Chuck < Object
  def norris
    puts "the man"
  end
end
chuck_norris = Chuck.new
p chuck_norris.respond_to?("norris") # true
p chuck_norris.respond_to?("mr_t") # false

Já o respond_to, sem o ponto de interrogação (eles fazem parte do nome do método) faz parte do ActionController do Ruby On Rails. Ele coloca suporte a Web Service na sua aplicação, isso quer dizer que ele consegue resolver o tipo do recurso que você deseja.

respond_to do |format|
  format.html # render por default nome_da_acao.html.erb
  format.js # render o nome_da_acao.rjs
  format.xml { render :xml => @chuck.to_xml } # coloca o chuck pra xml e envia
end

Com esse código na action você poderia usar, por exemplo:

http://localhost:3000/nome_da_acao.html
http://localhost:3000/nome_da_acao.xml

Ou realizar uma chamada JS unobstrusive usando AJAX.

Isso ai, espero ter ajudado.

Export the database models to YML fixtures

Hi Sirs,

Many tutorials over the web shows how to load data from fixtures. But, if you want to migrate your mysql data to a postgresql database?

We can export our data to fixtures, and after that we can load the fixtures to every database management system we wish.

Let's go to the rake task:

desc "export the database models to YML fixtures" 
task(:models_to_fixtures => :environment) do 
  ActiveRecord::Base.establish_connection(
    :adapter => 'postgresql', # mysql, sqlite3
    :encoding => 'utf8',
    :database => 'cnxs_development',
    :username => 'username',
    :password => 'secret'
  )
  ActiveRecord::Base.connection

  if ENV['MODELS'].nil? || ENV['MODELS'].blank?
    raise "Please enter valid models names separated by coma. Ex: MODELS=User,Account"
  end

  models = ENV['MODELS'].split(',').collect { |arg| arg.camelize.constantize }

  models.each do |model|
    output = {}
    collection = model.find(:all)
    collection.each do |object|
      output.store(object.to_param, object.attributes)
    end
    file_path = "#{RAILS_ROOT}/tmp/#{model.table_name}.yml" # /tmp/
    File.open(file_path, "w+") { |file| file.write(output.to_yaml) }
  end
end

Here you need to fill your database attributes like you do in the /config/database.yml.

You will call the command line:

$ rake models_to_fixtures MODELS=<your model names separated by coma>

For example:

$ rake models_to_fixtures MODELS=User,Post

All your model data will be stored on /tmp/ directory.

Download this rake task here.

See you.

RSpec view test for render :partial with :locals?

I was working on some rspec views tests and I've noticed that partial renderization can be tricky.

For example, if we have an index page that renders the objects list in a partial template.

In my case I was testing using a 'GivingClub' list:

describe "giving_clubs" do
  before do
    @giving_clubs = [mock_model(GivingClub)]
    assigns[:giving_clubs] = @giving_clubs
  end

  it "expect render giving clubs list" do
    template.expect_render(:partial => "/giving_clubs/list", :locals => { :giving_clubs => @giving_clubs })
    render "/giving_clubs/index"
  end
end

Do not forget the assigns before call template.expect_render. Locals works fine in this way.

Clean Objects with find method

Hi Sirs.

An important trick on the famous ActiveRecord::Base find method.

When you are in development time of your application, and you do some query on your database query editor, is a good practice to use the limit clauses and selects just the columns you want.

In the find method we can do it with the :limit and :select arguments.

For example in our code when we try to authenticate some user we got it like:

find(:first, :conditions => [query, hash], :select => "id, email, login")

The returned object contains just the id, email and login attributes. Clean object.

Password and other attributes do not appears in the returned object =]

Simple development practice, but very important too.

See you.

SQL Lite for Ruby On Rails

Hi all.

If your Operacional System is Ubuntu and you are using Ruby on Rails 2.0.2 you can easily use it:

$ sudo apt-get install sqlite3
$ sudo gem install sqlite3-ruby

SQLite3 does not use authentication and needs only a pointer to the database file on database yml.

development:
  adapter: sqlite3
  database: db/development.sqlite3
  timeout: 5000
test:
  adapter: sqlite3
  database: db/test.sqlite3
  timeout: 5000
production:
  adapter: sqlite3
  database: db/production.sqlite3
  timeout: 5000

When you run "rake db:create:all" on your RAILS_ROOT it creates all 3 databases.

More information about other plataforms?

Here: http://wiki.rubyonrails.org/rails/pages/HowtoUseSQLite

See you.

Atom Feed Helper Example
Hi all,
Rails 2 makes the Atom RSS Feed much more sophisticated and elegant. If you are using the Ruby on Rails by RubyGems installer, maybe you have an old version of the Atom Feed Helper. To fix it you can check out the atom_feed_helper version inside the Ruby on Rails repository and after that, copy and paste it to /vendor/plugins/ directory.
The repository is: http://svn.rubyonrails.org/rails/plugins/atom_feed_helper.
In there you will find plugins that are more up to date.
In the README you will find a simple example to build your feed. Like when you click in our Cnxs feed at the navigation bar, if you are browsing with Firefox.
Here comes our example:
# rss.builder
atom_feed(:schema_date => @posts.last.created_at.year) do |feed|
  feed.title("CNXS")
  feed.updated(@posts.first ? @posts.first.created_at : Time.now.utc)
  @posts.each do |post|
    feed.entry(post) do |entry|
      entry.title(post.title)
      entry.content(post.body, :type => 'html')
      entry.author do |author|
        author.name(post.user.name)
        author.email(post.user.email)
      end
    end
  end
end
You can note the the atom_feed method has 4 arguments, but just one of them is required, that is the :schema_date. You can read at http://feedvalidator.org/docs/error/InvalidTAG.html, you see that the URI tag needs a year to be fix in the validators, month and day parts are optional. The others arguments are :language, that defaults to "en-US", :root_url, that defaults to the root path on the current host and :url that defaults to the current URL.
Another thing that you can look is that the ".builder" extension has higher precedence. So, if you code it in your rss action in the PostsController:
respond_to do |format|
  format.atom { render :layout => false }
end
the atom format respond int the same way to rss.builder and rss.atom.builder.
See you.
Work Environment
What's your work environment? Which IDE or whatever you use for code? I will describe mine:
I use Eclipse as my IDE for Rails Java or ColdFusion (I use a separate version/dist of Eclipse for each). I don't have too much to complain about memory usage, cause everytime I prefer spend a hundred bucks more on my pc's to get much more memory that I would use. By the way here's a tip for those who want to reduce the memory usage of Eclipse, or just want to not have some tools that they will not use (that's me!). Download only the Eclipse Plataform Binary (around 40MB) that comes without the JDT and without other unnecessary plugins.
Ok that will save some MB on your memory. Now build your own environment, with only plugins that you want!
Here is mine for Ruby on Rails: Aptana, RadRails, Subclipse.
ColdFusion: CFEclipse, Aptana, Subclipse
Java: WTP, Subclipse.
HTML Filtering with sanitize helper
Hi sirs,
another important feature that we need to use is the 'sanitize' helper. This Ruby on Rails helper filters HTML nodes and attributes and strips invalid protocols. Here in our case the use it on the simpler way:
<%= sanitize(post.body) %>
Other time you can choose the options ':tags' and ':attributes' to do a custom use where just the HTML tags and attributes pointed here are allowed to be interpreted.
It is another little tip that helps in malicious posts or comments containing javascripts codes or comments with different enconding. Here comes the Rails API link to more information about this: SanitizeHelper.
See you.
Ruby on Rails pagination

Hi sirs.

I really recommend the official Ruby on Rails paginator. Very easy to use. Like 95% of the plugins =).

I just checkout the project on SVN, change one line of code on my controller, appends a line of code on the ".html.erb" template index file, and paste a piece of CSS code on the stylesheet, and it works. The piece of CSS code is defined on the README file inside the plugin's root directory.

In my case, I just insert on my controller:

@posts = Post.paginate(:page => params[:page], :per_page => 10, :order => "created_at DESC")

and just insert on the view's bottom:

<%= will_paginate @posts %>

The CSS code I just change the color =).

The SVN repository is svn://errtheblog.com/svn/plugins/will_paginate.

The page that contains most of instructions is the err.the_blog, but if you just read the README in the will_paginate plugin you will be prepared to do all the work.

See you.

New file extensions on Ruby on Rails
The very best point to participate of a developers group like CNXS is when you found a problem, everyone tries to help faster they can.
Rafael Souza shows me this post on another blog and it helps a lot. Just change the extension ".rhtml" to ".html.erb" and ".rxml" to ".builder" on you Ruby on Rails application in version 2.0.2. Your problems is gone.
See you.
Problems on Ruby on Rails 2.0.2
Hi all,
Ruby on Rails 2.0.2 is released... and I do not like this version, because of 2 modifications.
1. Database default: Postgresql is my favorite database management system, but I know that Mysql is very easy to use on Windows and Linux. I respect the preference about Mysql. But I do not like what I read on "Riding Rails" that says "This is especially so under OS X 10.5 Leopard, which ships with SQLite3 and the driver gems preinstalled as part of the development kit". Sincerelly, for me, it is not a good point to change the default database :P
2. ".rxml" files was fired. Our feed on the site just blow up... because we use the .rxml files to render the xml version of the site.

Our host is using just Rails 2.0.2, living on the edge has problems too.
=)
See you.
Filter sensitive information on logs

Hi Sirs,

a very important thing that I can remember about security on web environment is 'logs'.

Ruby on Rails provide a very simple way to protect us of store sensitive information on the logs. Every information that goes through the parameters is writed on the log. In websystem development phasis logging information is important, but in the production phasis, is dangerous. Hackers in general can take information through many ways. Our tip to protect sensitive information in the logs is the method 'filter_parameter_logging' of the Class ActionController::Base.

ActionController is the mother class of every controller in your applications, so the best place to call it is in the app/controllers/application.rb.

Just insert this example line of code:

filter_parameter_logging :password, :password_confirmation

and than it replaces the values of all keys that matches the arguments name with "[FILTERED]", and you are protecting your informations in the logs.

Is a simple tip, but very important. Do not forgot to use it.

See you.

Rails 2

Hi all,

I am very happy to give you the notice that our website here, is installed in Ruby on Rails 2.0.1 just 3 days after the release is finished. Installed and tested in the weekend =].

That's the way that the CNXS team likes to work. Ever living on the edge.

Congratulations to Ruby on Rails Development Staff and to CNXS Team.

See you sirs.

Introduction to cnxs

Hey Folks. This is the first post, so I'll manage to keep myself away from technological ramblings and just say some words about us and our purpose here.

This is not exactly a company, it is more a group of friends with some mutual interests who got together because they thought it would be fun to do it and each could learn and teach the others a lot.

What bought us together here is a passion for developing good software, with tools that help us not only accomplish this, but to have some fun while we are doing it. We like what we do, and I can say that we don't view this as a job, but as a pleasant thing, which fortunately happens to be payed sometimes (yay). I think that's that for now, but we'll be back tomorrow.

Hugs everyone, and welcome to the joy of connected thoughts :D