Posts Tagged 'Ruby on Rails'

ActionMailler and Gmail (no plugins)

Last week I had some problems while trying to configure the ActionMailler with Gmail. I already have some applications in production mode recurring to this system, but this one, using ruby 1.8.7 and rails 2.3.3 gave me some trouble. Gmail requires TLS, older versions of ruby and rails do not support that, the work around was a pluging to enhance it(for example ActionMailerTLS). If you are using Ruby 1.8.7 and Rails 2.2.1, or later versions, you don’t need any plugin, you only need to follow my instructions.

Add the following lines in your config/enviroments/production.rb

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = YAML.load File.open("#{RAILS_ROOT}/config/mailer.yml")

And then create the yaml file config/mailer.yml :

---
  :enable_starttls_auto: true # This is how you tell ActionMailler to use tls
  :address: smtp.gmail.com
  :port: 587
  :domain: gmail.com
  :user_name: my_username #You should type your username, you should not include the "@gmail.com".
  :password: my_password #You should type your password
  :authentication: :plain

That’s it!

Now take a look in this notifier class example:

class Notifier < ActionMailer::Base
  def activation_instructions(user)
    @recipients  = "#{user.email}"
    #@from        = "Miguel <my_username@gmail.com>" # Doesn't work anymore 
    @from        = "my_username@gmail.com"
    @subject     = "[Card-Sorting] "
    @sent_on     = Time.now
    @subject    += "Important"
    @body[:user] = user
  end
end

There is a lack of backward compatible. Due to some changes in the latest versions you cannot use that syntax anymore, if you are upgrading from old versions be careful, you should only simply specify your email to get it correctly parsed.

Git diff pacth

How to create a patch with git diff:

git diff HEAD~2 > changes.diff


How to use it:

patch -Np2 -i changes.diff

thanks to Andy ;)

Hash to Object

Sometimes I have the need to create objects that responds to some methods with a specific values.
Something that I can use like
HashObject.new :method1 => value_for_method1, :method2 => value_for_method2
There is already a way to do it, with OpenStruct, but I created a HashObject. Just for academic proposals. I didn’t knew the OpenStruct at the time.

class HashObject
  def initialize(hash)
    hash.each do |k,v|
      self.instance_variable_set("@#{k}", v)
      self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
      self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})
    end
  end

  def to_hash
    hash_to_return = {}
    self.instance_variables.each do |var|
      hash_to_return[var.gsub("@","")] = self.instance_variable_get(var)
    end
    return hash_to_return
  end
end

Javascript auto include rails plugin

I need to check this link latter:

http://blog.media72.net/2008/05/13/javascript-auto-include-rails-plugin/

I haven’t tried it yet but seems a good way to maintain your .js files organized.

Get all values of a single column efficiently

Imagine you want this:

@names = MyModel.find(:all).map{ |i| i.name }.uniq

Yes, that works! You get all distinct names of one column, you can even do something like that:

#Using Shortcut Blocks with Symbol to_proc
@names = MyModel.all.map(&:name).uniq

Cool, rely small code(almost seems I’m using Haskel) but not that efficient if your model’s table has lots of columns. (Imagine! The whole table is being loaded to memory) So what is the solution?

MyModel.find( :all, :select > 'DISTINCT name' )

If you specify wich columns you need, in the sql query, you will spare some memory. And in my earlier example you can also pass the “uniq” work to the database.

will_paginate without losing params

I’m sure you like will_paginate, it seams magic! But I was having the issue, that I simply solved like that:

will_paginate(@reports, :params => params.except(:page))

Rewrite humanize

I have an application with all tables and field names in English, but the whole views now need to be in Portuguese.

Because I’m always using the humanize method, a simple solutions should emerge.

First solution:

class Ticket
  HUMANIZED_ATTRIBUTES = {
    :category > "Categoria",
    :title > "Assunto"
  }
  def self.human_attribute_name(attr)
    HUMANIZED_ATTRIBUTES[attr.to_sym] || super
  end
end


Setting the human_attribue_name in each model works ok,
but if like in my case, you have 20 models and all of them have a description, title,… much duplication…

So I thought in doing something similar to this in my enviroment.rb:

Inflector.inflections do |inflect|
  inflect.plural /^(foo)$/i, '\1ze'
  inflect.singular /^(foo)ze/i, '\1'
end


But for the humanized method instead of pluralize. Yah It would make sense that way, but rails doesn’t provide that feature. You can go here to find a patch for getting that functionality into your rails, I hope they get that into the core… anyway If didn’t want to download the patch, how do I solve the problem?

Maybe a rubbish solution but perfect to get what I was needing, translate my views with few lines of code!
What I’ve done? Just added those lines into my environment.rb

class String
  def humanize
    {:movie              => "Filme",
     :movies             => "Filmes",
     :name               => "Nome",
     :title              => "Título",
     :synopsis           => "Sinopse",
     :genre              => "Genero",
     :author             => "Autor",
     :authors            => "Autores"
     ...
    }[self.gsub(/_id$/, "").to_sym] || super
  end
end


I simply redefined the humanize method for whole strings. It works perfectly in my case, because I’m always calling humanize in my views.

keep humanizing the world!

Ruby on Rails no Ubuntu

As seguintes instruções demonstram como instalar o framework ruby on rails. Os comandos abaixo listados, foram por mim executadas exactamente após a instalação do Ubuntu 8.10.

Não deve ser necessário editar os repositórios. Mas fica o comando apenas para referencia.

sudo vim /etc/apt/sources.list

Pode pensar que full-upgrade inclui o safe-upgrade, mas é mentira são comandos diferentes. Portanto aconselho a intoduzir os dois pela seguinte ordem:

sudo aptitude safe-upgrade
sudo aptitude full-upgrade

Nesta fase é responder Yes a todas as perguntas!

sudo aptitude install build-essential

(Como disse estou a descrever os passos exactos que executei após a instalação do SO)
Agora sim vamos ao importante:

sudo aptitude install ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8 libopenssl-ruby sqlite3 libsqlite3-ruby1.8

Criar alguns symlinks:

sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby
sudo ln -s /usr/bin/ri1.8 /usr/bin/ri
sudo ln -s /usr/bin/rdoc1.8 /usr/bin/rdoc
sudo ln -s /usr/bin/irb1.8 /usr/bin/irb

Agora vamos instalar o rubygems que nos oferece o comando gem, uma espécie de aptitude para o ruby.
Deve verificar qual a ultima versão de rubygems(http://rubyforge.org/projects/rubygems/), no caso de existir uma versão mais recente, substituir no comando em baixo.

wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
tar xzvf rubygems-1.3.1.tgz
cd rubygems-1.3.1
sudo ruby setup.rb

Criar symlink e garantir que temos o rubygems actualizado

sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
sudo gem update
sudo gem update --system

E finalmente instalar o Ruby on Rails.

sudo gem install rails

Confirmar que tudo correu bem.
sudo gem list
Devemos obter uma lista deste genero:
*** LOCAL GEMS ***

actionmailer (2.2.2)
actionpack (2.2.2)
activerecord (2.2.2)
activeresource (2.2.2)
activesupport (2.2.2)
rails (2.2.2)
rake (0.8.3)

Verificar a operabilidade do sistema de base de dados sqlite:

irb
.......
irb(main):001:0> require 'sqlite3'
=> true
irb(main):002:0> exit

Para criar o primeiro projecto:

rails nome_do_meu_projecto

Já agora instalar o rmagick possivelmente tambem será util para a maioria dos projectos.

sudo aptitude install imagemagick
sudo aptitude install libmagick9-dev
sudo gem install rmagick

Agora é só por mãos a obra… e talvez arranjar um bom editor. Aconselho o textmate ou o vim, descreverei em breve como configurar e instalar alguns plugins para rails, no caso de escolher o vim.

Laurel and Hardy Archive Explained

A screencast showing some of the new laurelandhardyarchive.com feathers.

PayPal Payments Standard, Subscriptions and IPN with Ruby on Rails.

Hi there!
 
I spend the last week struggling with PayPal documentations and with their buggy sandbox. The information is not well organized, and you can spend hours jumping between pages and pdf to find out what you want, I’m sure they like treasure hunt   games, I remember to following  10 steps, described on a pdf,  to download a sample code, (you should click this link, and now try to find a small square in the middle of the page, press it  and then you should close your eyes for about… crazy weirdoes) anyway… my goal was to implement a subscription system for laurelandhardyarchive, and of course because is subscriptions, with PayPal at UK, with IPN, and using rails, everything seems to be a little more difficult (only at the beginning ;) ), PayPal doesn’t provide any ruby samples, and there is a good plugin Active Merchant, but again because it’s subscription, the documentations also fails(not only for subscriptions, the whole Active Merchant  has a lack of documentation). With that scenario I figure out the best way to solve the problem was to build my own gem to deal with that, the gem should be finished soon, but anyway I leave you a small brief of what is needed to accomplish this, and I leave you some links, so that way you don’t need to a treasure hunt throw PayPal web site.
 
So… do you need to integrate PayPal subscriptions and IPN into your web site?
 
For starting you should register into developer PayPal then you should create two sandbox PayPal  accounts to do your tests (you can use the preconfigured account button for those, but be aware to chose country US even if you are in UK, because you will have troubles to activate the test account, but don’t worry you real account should not have any problems based in the country),  one of the account should be busyness type and the other personal type account, you will use them  to simulate the seller and buyer roles, don’t forget to start the personal account (the buyers one) with some money(fake money) you can do that while creating it, click the advanced otptions drop down.
 
So right now you can use your business account to create code for subscription buttons. For doing that you should access PayPal sandbox, in the developers page (when listing the accounts) you have a link for that. PayPal sandbox is a complete copy of the original PayPal web site, and all test accounts can interact in this closed world.
 
This is all for now. I’ll try to post some code latter. In any case if you’re trying to achive something similar and having some difficulties, leave me a message, if have the knowledge to I be glade to help.


Last Regedor’s twitts

Last Regedor's bookmarks