Forum: Rails-ES Duda sobre eliminación de un registro c on registros asocia

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
E91518f050cb6081186ff461950099e0?d=identicon&s=25 Luis Villegas (Guest)
on 2007-02-23 14:20
(Received via mailing list)
Buenas, me ha surgido una duda:

Si tengo una tabla Personas y otra perros que está asociada a persona.

Creo una persona: Id: 1 nombre: luis
Creo un perro para esa persona: id : 1 nombre: perrito persona_id: 1

Borro persona y salta una excepción de sql

Mi pregunta es: ¿Hay algún método ya implementado en rails para que
valide
que la persona no tenga perros asociados?

Gracias
9b3b1fd6baa8379638d8399ecd60045d?d=identicon&s=25 Emili Parreño (emili)
on 2007-02-23 14:25
Acabo de hacer la misma pregunta que tu en el mismo minuto :)
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-02-23 16:10
(Received via mailing list)
On Feb 23, 2007, at 2:19 PM, Luis Villegas wrote:

> Buenas, me ha surgido una duda:
>
> Si tengo una tabla Personas y otra perros que está asociada a persona.
>
> Creo una persona: Id: 1 nombre: luis
> Creo un perro para esa persona: id : 1 nombre: perrito persona_id: 1

La regla es:

Cada vez que tus dedos tecleen has_many|has_one, te ha de saltar un
trigger en la cabeza que te haga tomar una decision sobre la
opcion :dependent.

-- fxn
B8eb6140a480852282b1deb8f7987a24?d=identicon&s=25 Silvio Quadri (Guest)
on 2007-02-23 17:13
(Received via mailing list)
Aprovecho el hilo para preguntar ...
no hay un :dependent => :reject     ?
La verdad que consulte la api y solo veo   :destroy,  :delete_all  o
:nullify

Silvio

El día 23/02/07, Xavier Noria <fxn@hashref.com> escribió:
B8eb6140a480852282b1deb8f7987a24?d=identicon&s=25 Silvio Quadri (Guest)
on 2007-02-23 17:17
(Received via mailing list)
Lo acaban de responder en otro mail ... esto me pasa por leer de atras
para
adelante.
Silvio

El día 23/02/07, Silvio Quadri <silvioq@gmail.com> escribió:
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-02-23 17:26
(Received via mailing list)
On Feb 23, 2007, at 5:12 PM, Silvio Quadri wrote:

> Aprovecho el hilo para preguntar ...
> no hay un :dependent => :reject     ?

Con http://www.redhillconsulting.com.au/
rails_plugins.html#foreign_key_associations las migrations normales
crean foreign keys transparentemente en aquellas bases de datos que
las soportan. Nosotros lo usamos en todos los proyectos.

-- fxn
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 13:41
(Received via mailing list)
Hola,

Precisamente he estado peleándome con los tres plugins de redhill
estos dias (versiones para rails 1.1.6):

redhillonrails_core
foreign_key_associations
foreign_key_migrations

Dada la siguiente migración:

class AddForeignKeys < ActiveRecord::Migration
  def self.up

    add_column :systems, :zone_id, :string
  add_column :ips, :zone_id, :string
  add_column :ips, :mac_id, :string
  add_column :macs, :system_id, :string
  add_column :macs, :port_id, :string
  add_column :ports, :system_id, :string

=begin
    add_foreign_key :systems, :zone_id, :zones, :id, :on_delete =>
:set_null, :on_update => :cascade
  add_foreign_key :ips, :zone_id, :zones, :id, :on_delete => :set_null,
:on_update => :cascade
  add_foreign_key :ips, :mac_id, :macs, :id, :on_delete => :set_null,
:on_update => :cascade
  add_foreign_key :macs, :system_id, :systems, :id, :on_delete =>
:set_null, :on_update => :cascade
  add_foreign_key :macs, :port_id, :ports_id, :id, :on_delete =>
:set_null, :on_update => :cascade
  add_foreign_key :ports, :system_id, :systems, :id, :on_delete =>
:set_null, :on_update => :cascade
=end
  end

  def self.down
    remove_column :systems, :zone_id
  remove_column :ips, :zone_id
  remove_column :ips, :mac_id
  remove_column :macs, :system_id
  remove_column :macs, :port_id
  remove_column :ports, :system_id
  end
end

Me falla al intentar establecer la FK (añade bien la columna
previamente):

$ rake migrate
(in /home/brainstorm/uni/PFC/rubynac/railsnac)
== AddForeignKeys: migrating
==================================================
-- add_column(:systems, :zone_id, :string)
rake aborted!
Mysql::Error: Can't create table
'./railsnac_development/#sql-3632_2c.frm' (errno: 150): ALTER TABLE
systems ADD FOREIGN KEY (zone_id) REFERENCES zones (id)

(See full trace by running task with --trace)

(En este punto, en la BBDD se ha creado zone_id... la migration no
deberia hacer rollback si ha fallado en un punto intermedio :-? (en la
primera instrucción en este caso))

Yo creo que el schema.db está "correcto" :-S:


ActiveRecord::Schema.define(:version => 6) do

  create_table "ips", :force => true do |t|
    t.column "ip", :string
  end

  create_table "macs", :force => true do |t|
    t.column "mac", :string
    t.column "oid", :string
  end

  create_table "ports", :force => true do |t|
    t.column "location", :string
    t.column "portid", :string
  end

  create_table "systems", :force => true do |t|
    t.column "oid", :string
    t.column "username", :string
  end

  create_table "zones", :force => true do |t|
    t.column "oid", :string
    t.column "name", :string
    t.column "active", :string
    t.column "hostmaster", :string
    t.column "serial", :string
    t.column "serial_date", :string
    t.column "type", :string
  end
end

Alguna idea de pq falla ? Parte de --trace al hacer migrate:

usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract_adapter.rb:120:in
`log'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:184:in
`execute'
/home/brainstorm/uni/PFC/rubynac/railsnac/config/../vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core.rb:56:in
`add_foreign_key'
/home/brainstorm/uni/PFC/rubynac/railsnac/config/../vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations.rb:30:in
`add_column'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:273:in
`send'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:273:in
`method_missing'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:257:in
`say_with_time'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:257:in
`say_with_time'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:271:in
`method_missing'
./db/migrate//007_add_foreign_keys.rb:4:in `real_up'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:210:in
`send'

Saludos & thx !
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-02-24 14:22
(Received via mailing list)
On Feb 24, 2007, at 1:40 PM, brainstorm wrote:

> './railsnac_development/#sql-3632_2c.frm' (errno: 150): ALTER TABLE
> systems ADD FOREIGN KEY (zone_id) REFERENCES zones (id)

La tabla zones existe en el momento de ejecutar esa migration?

-- fxn
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 14:44
(Received via mailing list)
Si, existe con todas las columnas creadas (comprobado con phpmyadmin).
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-02-24 15:52
(Received via mailing list)
On Feb 24, 2007, at 2:42 PM, brainstorm wrote:

> Si, existe con todas las columnas creadas (comprobado con phpmyadmin).

Es muy raro, te es posible tirar para atras el esquema y volver a
ejecutar db:migrate desde un punto en el que sabes que esta consistente?

-- fxn
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 16:04
(Received via mailing list)
No, hago "rake migrate VERSION=6" (esquema justo anterior) y se queda
igual (porque no ha conseguido migrar a 7 (AddForeignKeys))
completamente.

Tengo que ir a la DB, y borrar manualmente "zone_id" de "systems". Sino:

$ rake migrate
(in /home/brainstorm/uni/PFC/rubynac/railsnac)
== AddForeignKeys: migrating
==================================================
-- add_column(:systems, :zone_id, :string)
rake aborted!
Mysql::Error: Duplicate column name 'zone_id': ALTER TABLE systems ADD
`zone_id` varchar(255)

Lo dicho: no me hace rollback al fallar la migración :-(
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 16:17
(Received via mailing list)
Por cierto, en los modelos tengo:

class Zone < ActiveRecord::Base
  has_many :ips, :dependent => true
  has_many :systems, :dependent => true
end

class System < ActiveRecord::Base
  has_many :macs, :dependent => true
  has_many :ports, :dependent => true    # Multihoming
  has_many :ips, :dependent => true    # IP aliasing
(...)

Siguiendo la el consejo de Xavier sobre los "dependent"...
49b6123803e4f327144e991daab62f77?d=identicon&s=25 Daniel Rodriguez Troitiño (Guest)
on 2007-02-24 16:20
(Received via mailing list)
On 2/24/07, brainstorm <braincode@gmail.com> wrote:
>
> (En este punto, en la BBDD se ha creado zone_id... la migration no
> deberia hacer rollback si ha fallado en un punto intermedio :-? (en la
> primera instrucción en este caso))
>

No se que te puede estar pasando, pero preguntas sobre los rollback
cuando fallan las migration y según leí en algún lugar esto no es
posible en muchas bases de datos y Rails por lo tanto no lo hace.

En las BBDD hay dos tipos de comandos SQL, de definición de datos y de
manejo de datos, sólo los segundos pueden ser transaccionales en la
mayoría de BBDD modernas. Crear tablas, indices, añadir columnas,
etcéteras normalmente no pueden ser transaccionales en la mayoría de
BBDD.

No se si puedes rodear las lineas dentro del self.up y self.down por
bloques de transacción. Quizá si tu base de datos soporta
transacciones en ordenes de definición de datos te funcione.

De cualquier forma las migration están pensadas para no fallar en
producción. Si fallan en la base de datos de desarrollo no debería ser
importante (solo molesto). Por eso es muy importante probar las
migration muy bien durante el desarrollo, un fallo en producción puede
ser muy embarazoso.
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-02-24 16:27
(Received via mailing list)
On Feb 24, 2007, at 4:03 PM, brainstorm wrote:

> No, hago "rake migrate VERSION=6" (esquema justo anterior) y se queda
> igual (porque no ha conseguido migrar a 7 (AddForeignKeys))
> completamente.

OK, el siguiente paso es reproducir esto con un ejemplo minimo.
Podrias por favor crear una aplicacion 1.1.6 nueva con dos migrations
minimas donde esto suceda y enviar esas migrations? Envia tambien por
favor la version del plugin.

-- fxn
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 16:42
(Received via mailing list)
Ok, he probado con:

  self.transaction do
    add_column :systems, :zone_id, :string
    add_column :ips, :zone_id, :string
    add_column :ips, :mac_id, :string
    add_column :macs, :system_id, :string
    add_column :macs, :port_id, :string
    add_column :ports, :system_id, :string
  end

Pero el efecto es el mismo (crea la columna zone_id en systems y no
hace rollback). Por lo que leo en la API:

"Also have in mind that exceptions thrown within a transaction block
will be propagated (after triggering the ROLLBACK)"

Por tanto entiendo que deberia hacer el rollback tanto si capturo la
excepción como si no :-(... podria ser problema del driver mysql ?
(uso gem ruby mysql 2.7).

Sin embargo, ahora mismo me preocupa bastante más el porqué no puede
establecer correctamente las FK, lo del rollback es un problema
"menor" en mi situación actual :-S

PD: Creo que no lo habia dicho hasta ahora: uso MySQL.

Gracias por la explicación ;)
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 16:45
(Received via mailing list)
Ok, me pongo a ello immediatamente.

Si por la versión del plugin te refieres a los de redhill son estas:

The latest Rails 1.1.6 version of the plugin is available from
svn://rubyforge.org/var/svn/redhillonrails/tags/release-1.1.6/vendor/plugins/foreign_key_migrations
svn://rubyforge.org/var/svn/redhillonrails/tags/release-1.1.6/vendor/plugins/foreign_key_associations
svn://rubyforge.org/var/svn/redhillonrails/tags/release-1.1.6/vendor/plugins/redhillonrails_core

El "plugin"/gema de mysql es 2.7 tal como comentaba en el mail anterior.
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 17:02
(Received via mailing list)
He reproducido el error :-! Aqui tienes las migrations que he usado:

brainstorm@brainmachine ~/tmp/fk_killing_me $ cat db/migrate/00*
class CreateMacs < ActiveRecord::Migration
  def self.up
    create_table :macs do |t|
      t.column :mac, :string
    end
  end

  def self.down
    drop_table :macs
  end
end
class CreateIps < ActiveRecord::Migration
  def self.up
    create_table :ips do |t|
      t.column :ip, :string
    end
  end

  def self.down
    drop_table :ips
  end
end
class CreateZones < ActiveRecord::Migration
  def self.up
    create_table :zones do |t|
      t.column :name, :string
    end
  end

  def self.down
    drop_table :zones
  end
end
class AddForeignKeys < ActiveRecord::Migration
  def self.up
          add_column :macs, :ip_id, :string
  end

  def self.down
          remove_column :macs, :ip_id
  end
end

Y exactamente el mismo error:

brainstorm@brainmachine ~/tmp/fk_killing_me $ rake migrate --trace
(in /home/brainstorm/tmp/fk_killing_me)
** Invoke migrate (first_time)
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:migrate
== AddForeignKeys: migrating
==================================================
-- add_column(:macs, :ip_id, :string)
rake aborted!
Mysql::Error: Can't create table
'./fk_killing_me_development/#sql-3632_d0.frm' (errno: 150): ALTER
TABLE macs ADD FOREIGN KEY (ip_id) REFERENCES ips (id)
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract_adapter.rb:120:in
`log'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/mysql_adapter.rb:184:in
`execute'
/home/brainstorm/tmp/fk_killing_me/config/../vendor/plugins/redhillonrails_core/lib/red_hill_consulting/core.rb:56:in
`add_foreign_key'
/home/brainstorm/tmp/fk_killing_me/config/../vendor/plugins/foreign_key_migrations/lib/red_hill_consulting/foreign_key_migrations.rb:30:in
`add_column'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:273:in
`send'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:273:in
`method_missing'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/migration.rb:257:in
`say_with_time'

Modelos:

brainstorm@brainmachine ~/tmp/fk_killing_me $ cat app/models/*.rb
class Ip < ActiveRecord::Base
        belongs_to :mac
        belongs_to :zone
end
class Mac < ActiveRecord::Base
        has_may :ips
end
class Zone < ActiveRecord::Base
        has_many :ips
end

Gracias por la ayuda !
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 17:19
(Received via mailing list)
Oops, he encontrado un thread en la lista inglesa de un railero que le
pasa lo mismo, y al parecer nadie ve la solución :-/:

http://groups.google.com/group/rubyonrails-talk/tr...

Xavier está en el thread también... me vienen unas cuantas preguntas:

Desde cuando usais este plugin ? En 1.1.6 os ha funcionado siempre ?
Siempre lo usais con create_table ? Alguna vez con add_column como es mi
caso ?

Gracias !
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 17:45
(Received via mailing list)
De los mismos creadores de los plugins de las foreign keys (redhill):

svn://rubyforge.org/var/svn/redhillonrails/tags/release-1.1.6/vendor/plugins/transactional_migrations

"Transactional Migrations is a plugin that ensures your migration
scripts—both up and down—run within a transaction. When used in
conjunction with a database that supports transactional Data
Definition Language (DDL)—such as PostgreSQL—this ensures that if any
statement within your migration script fails, the entire script is
rolled-back."

Lo he instalado pero ... tampoco funciona: al hacer la migration no
hace el up de forma atómica ! :/

Hoy no es mi dia con rails :-S
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-02-24 18:25
(Received via mailing list)
On Feb 24, 2007, at 5:02 PM, brainstorm wrote:

>   def self.down
>   def self.down
>   def self.down
>     drop_table :zones
>   end
> end
> class AddForeignKeys < ActiveRecord::Migration
>   def self.up
>           add_column :macs, :ip_id, :string
>   end

Ah, ya lo veo, es por el esquema. No tiene que ver ni el plugin ni
add_column.

La columna ip_id de la tabla MACS por convenio hace referencia a la
columna id de la tabla IPS, pero esa columna es un entero, no una
cadena. Si querias apuntar al campo ip entonces tendras que
investigar que constraints ha de cumplir una columna de tipo string
para que puedan apuntar FKs a ella, me extrañaria que asi
silvestremente funcione. Aqui dice alguna cosa:

   http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-
constraints.html

-- fxn
D3ac444b32831e42e45534de7ba89b84?d=identicon&s=25 brainstorm (Guest)
on 2007-02-24 21:30
(Received via mailing list)
Gracias, solventado :-)

Creo que he tirado por la via más fácil (estandar?): canviar el tipo
de string a integer de las FK's. He visto que typo lo hace así.

La pega es que tendré columnas con info no útil (id's de otras tablas,
sólo para hacer joins).

Otra alternativa supongo que seria explicitar más cada FK, sin usar
id's:

:references => mac
:references => etc...

Cómo teneis implementado este tema en vuestros proyectos ?

Saludos & gracias a todos !

(y disculpas por el thread kilométrico :S)
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (Guest)
on 2007-02-24 22:16
(Received via mailing list)
On Feb 24, 2007, at 9:29 PM, brainstorm wrote:

> Gracias, solventado :-)

Fenomenal.

>
> Cómo teneis implementado este tema en vuestros proyectos ?

La pauta que seguimos, no escrita en ningun sitio :-), es que las FKs
han de llamarse de una manera que tenga sentido en el argot del
modelo. Eso da el nombre, y la necesidad de usar :references o no es
consecuencia de esa eleccion. Hacer joins por ID para recuperar un
campo es muy normal.

-- fxn
This topic is locked and can not be replied to.