jueves, enero 22, 2009

gul-nic@mansion_teodolinda:~$ pizza_bash2

Acompañanos a la segunda edición de pizza_bash una reunión para hablar de SL y claro comer pizza ;)

Cuando? vie ene 23 03:00:00 CST 2009
Donde? Mansión Teodolinda

RoR: Agregar FK a una tabla

En RoR resulta muy cómodo utilizar la herramienta rake para manejar la estructura de una BD así como el cambio de versiones. Recientemente me topé con el caso de necesitar agregar una llave externa FK a una tabla existente, en intente hacer la referencia normalmente según rake
ruby script/generate migration add_comment_to_post post:reference
Pero esto no resultó, luego de horas de búsqueda y lectura me doy cuenta que no es posible agregar una FK a una tabla existente utilizando el generador migrate pero que si se puede hacer manualmente y reutilizarse par futuro.

Creemos la migración,
ruby script/generate migration add_post_to_commet


luego vamos a editar db/migrate/XXXX_add_post_to_comment.rb como nos sugiere el nombre, vamos a pasar el id de la tabla post a la tabla comment.
#add_user_to_post.rb
require "migration_helpers"

class AddUserToPost < ActiveRecord::Migration
extend MigrationHelpers

def self.up
#add_foreign_key (:mainentity, :mainentity_id, secundaryentity)
add_foreign_key(:users, :id, :posts)
end

def self.down
#add_foreign_key (:mainentity, :mainentity_id, secundaryentity)
remove_foreign_key(:users, :id, :posts)
end

end
Para comprender lo que acabamos de hacer hay que crear el siguiente helper helpers/migration_helpers.rb
#migration_helpers.rb
module MigrationHelpers

def add_foreign_key(from_table, from_column, to_table, options = {})
constraint_name = foreignkey_name(from_table, to_table)
column_name = foreignkey_column_name(from_table, from_column)

execute %{alter table #{to_table} add #{column_name} INT not null} if options[:add_column]
execute %{alter table #{to_table}
add constraint #{constraint_name} foreign key
#{index_name(column_name)} (#{column_name}) references #{from_table}(#{from_column})
#{ options[:cascade].map{ |cas| " ON #{cas} CASCADE" }.join if options[:cascade] }
}
end

def remove_foreign_key(from_table, from_column, to_table, options = {})
constraint_name = foreignkey_name(from_table, to_table)
column_name = foreignkey_column_name(from_table, from_column)

execute %{alter table #{to_table} drop foreign key #{constraint_name}}
execute %{alter table #{to_table} drop #{column_name}} if options[:remove_column]
end

def create_index(table, *columns)
execute %{create index #{index_name(columns)} on #{table} (#{columns.join(',')}) }
end

def remove_index(table, *columns)
execute %{drop index #{index_name(columns)}on #{table}}
end

private
def foreignkey_column_name(from_table, from_column)
"#{from_table.to_s.singularize}_#{from_column}"
end

def foreignkey_name(from_table, to_table)
"fk_#{from_table}_to_#{to_table}"
end

def index_name(*columns)
"idx_#{columns.join('_')}"
end
end
Con esto estamos listos para hacer
rake db:migrate
y se crea una nueva columna llamada post_id en la tabla comments utilizando rake migrations al igual que se destruye cuando se cambia de version.

La historia completa: http://railsforum.com/viewtopic.php?pid=85698

Resumen de Inicio de Año

Bastante tiempo paso desde la ultima actualización. Para ponerlos al día debo comentar que:
  1. 2008 se llevó mi empleo :( estoy temporalmente desempleado.
  2. Me compré una laptop de ensueño (puede que no tanto si te gastaste tus ahorros en ello)
  3. Sigo trabajando en http://www.telovendo.com.ni
  4. Estoy aprendiendo RoR y Android a toda marcha
  5. Apuntando a trabajar freelance