Archive for October 2008


Rails: Orden de carga de los plugins

October 19th, 2008 — 04:57 pm
madtrick:~/programacion/ror/diary madtrick$ ruby script/server webrick
=> Booting WEBrick...
/opt/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1667:in `method_missing': undefined local variable or method `acts_as_authorizable' for #<Class:0x336e194> (NameError)
        from /Users/madtrick/programacion/ror/diary/app/models/user.rb:21
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:215:in `load_without_new_constant_marking'
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:215:in `load_file'
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:354:in `new_constants_in'
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:214:in `load_file'
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:95:in `require_or_load'
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:60:in `depend_on'
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:456:in `require_dependency'
        from /Users/madtrick/programacion/ror/diary/vendor/plugins/authentication_system/lib/authentication_system.rb:1
        from /opt/local/lib/ruby/vendor_ruby/rubygems/custom_require.rb:27:in `gem_original_require'
        from /opt/local/lib/ruby/vendor_ruby/rubygems/custom_require.rb:27:in `require'
        from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.rb:509:in `require'
...

Eso fue lo que me encontre hoy al ir a probar unas cosillas en Rails.

El problema deriva del orden en el que se cargan los plugins residentes en $RAILS_ROOT/vendor/plugins, que a parecer es lexicografica, con lo cual yo me encontraba en la situacion de que el plugin A hacia uso del modelo M pero a su vez este modelo hacia uso de un metodo “mixeado” en ActiveRecord::Base por el plugin B.

Por lo tanto, como A se cargaba antes que B ya teniamos montado el belen.

Tras preguntarle al señor google que como arreglabamos este desaguisado, este primero me dijo que ya habia mas gente con este problema allá por el 2006 (1) y (2) y que finalmente la solucion por la que se opto fue la siguiente :

En environment.rb ponemos config.plugins = {:plugin1,:plugin2,:all} pudiendo controlar asi, el orden en el que se carga dichos plugins,cuales se cargan, etc.El simbolo :all, evidentemente se utiliza para cargar todos los demas plugins.

Actualizacion:

Soy algo cortito, si me hubiera molestado en leerme lo que ponia en environment.rb no habria tenido ningun problema.Extraido de environment.rb:

# Only load the plugins named here, in the order given. By default, all plugins
# in vendor/plugins are loaded in alphabetical order.
# :all can be used as a placeholder for all plugins not explicitly named

1 comment » | programacion, rails

Rails: Errores al instalar login_generator (1.2.2) en Rails 2.1.0

October 9th, 2008 — 05:07 pm

Si queremos utilizar el gem (o es “la” gem, no tengo muy claro el genero) en rails 2.1.0 nos vamos a encontrar con lo siguientes problemas tras haberlo instalado:

Primer problema,cuando vamos a generar nuestro sistema de login.La extension de las plantillas nos causa el primer problemilla:

madtrick$ ruby script/generate login account
      create  lib/login_system.rb
      create  app/controllers/account_controller.rb
      create  test/functional/account_controller_test.rb
      create  app/helpers/account_helper.rb
      create  app/views/layouts/scaffold.rhtml
No such file or directory - /opt/local/lib/ruby/gems/1.8/gems/rails-2.1.0/ 
lib/rails_generator/generators/components/scaffold/templates/layout.rhtml

El error deriva de que el script que genera el login sigue considerando que las plantillas tienen extension .rhtml, cuando eso ya no es asi.Ahora las plantillas utilizan la extension .html.erb

Por lo tanto para solucionar este problema lo que debemos de hacer es modificar la extension del fichero solicitado en el generador , login_generator.rb en este caso.

En mi caso el fichero login_generator.rb se encuentra en /opt/local/lib/ruby/gems/1.8/gems/login_generator-1.2.2 en otros sistemas puede que sea /usr/local/lib/ruby/gems/1.8/gems/login_generator-1.2.2 o /ruby/local/lib/ruby/gems/1.8/gems/login_generator-1.2.2

Pasaremos de:

17
m.template "scaffold:layout.rhtml", "app/views/layouts/scaffold.rhtml"

A:

17
m.template "scaffold:layout.html.erb", "app/views/layouts/scaffold.rhtml"

Si ahora volvemos a intentar generar el sistema de login no tendremos ningun problema:

madtrick$ ruby script/generate login account
   identical  lib/login_system.rb
   identical  app/controllers/account_controller.rb
   identical  test/functional/account_controller_test.rb
   identical  app/helpers/account_helper.rb
overwrite app/views/layouts/scaffold.rhtml? \ 
 (enter "h" for help) [Ynaqdh] Y
       force  app/views/layouts/scaffold.rhtml
      create  public/stylesheets/scaffold.css
      create  app/views/account
      create  app/views/account/welcome.rhtml
      create  app/views/account/login.rhtml
      create  app/views/account/logout.rhtml
      create  app/views/account/signup.rhtml
      create  README_LOGIN

Segundo problema.Tras solventar lo anterior, estamos ansiosos por probar nuestro sistema de login asi que vamos a nuestro navegador y tecleamos: http://localhost:3000/account/login

En la anterior direccion asumimos lo siguiente:

  • Que el controlador que hemos creado para gestionar las funciones de login tiene por nombre AccountController
  • Que tenemos una ruta en routes.rb que funciona para esta peticion

Si probamos esto una bonita pantalla de error nos dara la bienvenida:

ArgumentError in AccountController#login
 
wrong number of arguments (0 for 1)

Bien, para solucionar esto debemos de modificar todos los @request.method que nos encontremos en nuestro controlador por @request.request_method para evitar colisiones con la palabra reservada de ruby method

Tras solucionar esto volvemos a probar nuestro sistema de login, pero un vez mas nos la dan con queso:

Segundo problema,

 NoMethodError in AccountController#login
 
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.request_method

Bien, bien.Veamos que pasa aqui.Como podemos observar el mensaje de error nos dice que el error ocurrio al tratar de evaluar nil.request_method.Pero oiga, como que nil!! Si yo estoy viendo @request.request_method.

Lo que pasa aqui es que en esta version de Rails, @request (al igual que @params, @session, @flash, @cookies, @headers, @response) ha quedado en desuso en favor de los “accessor methods” que tienen el mismo nombre que las variables pero sin la arroba.Es decir donde tenemos @request.request_method pasamos a tener request.request_method y asi sucesivamente.

Probamos los cambios y nos encontramos con el tercer problema:

 NoMethodError in Account#login
 
Showing account/login.rhtml where line #1 raised:
 
undefined method `start_form_tag' for #<ActionView::Base:0x35a61dc>

login.rhtml luce de la siguiente forma:

<%%= start_form_tag :action=> "login" %>
...
<%%= end_form_tag %>

start_form_tag, tambien esta en desuso, en su lugar debemos de utilizar form_tag.De esta forma login.rhtml nos queda de la siguiente forma:

<% form_tag '/account/login' do  %>
...
<% end %>

Ahora por lo menos podemos probar nuestro login.Lo probamos y tras hacer click en el boton de login,nos encontramos con el cuarto error,

 NoMethodError in AccountController#login
 
undefined method `find_first' for #<Class:0x365c8b0>

find_first es otro de los metodos en desuso.Debemos de cambiarlo por find, con el simbolo :first como primer parametro y la opcion :conditions con la condicion que teniamos en find_first.

Es decir, pasamos de:

find_first(["login = ? AND password = ?", login, sha1(pass)])

A:

find(:first,:conditions=>["login = ? AND password = ?", login, sha1(pass)])

Si volvemos a probar, adivinad que pasa….si, otro error.Por el quinto vamos,otra vez por elementos en desuso.En este caso se trata de la variable @session residente en el fichero login_system.rb.Cambiamos esta y las demas variables existentes en dicho fichero a sus “accesor methods” , guardamos y volvemos a probar… e-voilà!!

Funciona!!

Espero que todo este rollo le sea de ayuda a alguien : )

1 comment » | programacion, rails

Rails: Claves foraneas en las migraciones

October 8th, 2008 — 10:37 pm

Hay varias formas para indicar la restriccion que implica una clave foranea en nuestras tablas cuando estamos utilizando las migraciones para definir dichas tablas.

La primera y mas “tosca” consiste en indicar a pelo dicha restriccion:

class CreateOrder < ActiveRecord::Migration
   def self.up
      t.string :name
      t.integer :user_id
 
      execute "alter table table add constraint fk_table_user \ 
         foreign key (user_id) references users (id)"
 
   end
 
   ...
 
end

Pero tambien podemos aprovechar algun plugin para facilitarnos el trabajo.Es aqui donde entra en juego este plugin que descubri hoy.

Con este plugin podemos rehacer lo anterior de la siguiente forma:

class CreateOrder < ActiveRecord::Migration
   def self.up
      t.string :name
      t.integer :user_id
 
      t.foreign_key :users,:user_id,:id
 
   end
 
   ...
 
end

Bastante mejor, no?.Este plugin tiene disponible adaptadores para mysql y postgresql.

Aqui teneis los otros plugins que tienen disponibles.

2 comments » | programacion, rails