2009-02-05 12 views
8

tengo una migración DB así:campo id y sin opción de incremento automático en la migración

class CreateParticipations < ActiveRecord::Migration 
     def self.up 
     create_table(:participations, :primary_key => 'Seat') do |t|  
      t.integer :Seat 
      t.string :Nickname 
      t.string :Clan 
      t.string :FirstName 
      t.string :LastName 
      t.string :Email 
      t.boolean :Payed 

      t.timestamps 
     end 
     end 

     def self.down 
     drop_table :participations 
     end 
    end 

Ahora, el asiento se crea con un incremento automático. Sin embargo, no quiero eso. Lo quiero sin un incremento automático. Definiré a Seat en mi Lógica.

He estado buscando pero no puedo encontrar la manera de deshabilitar el auto_increment.

¿Cómo puedo hacer esto? Excepto por hacerlo manualmente en MySQL.

+0

¿Estás realmente seguro de que quieres hacer esto? Va en contra de la convención que funciona muy bien en todos los rieles y le causará mucho trabajo extra en el resto de su aplicación haciendo que esta excepción a la regla funcione en todas partes. Tal vez "asiento" en un campo en esta tabla con un índice único en su lugar. A menos que necesite esto para adaptarse a un esquema heredado de algún tipo, esta suele ser una mala idea. Lamentablemente, no sé la respuesta real a su pregunta. –

+0

Sé que aquí está animando a los muertos, pero un ejemplo relativamente trivial podría ser un modelo vinculado a un servicio que no sea de Rails y que gestione los identificadores dentro de ese servicio. No habría necesidad de un autoincremento dentro de Rails, porque tendría más sentido vincular la representación de Rails a la id de representación de servicios que no son Rails, en lugar de generar OTRA ID y gestionar OTRO conjunto de restricciones. Sin embargo, sin más detalles sobre la necesidad en la circunstancia original del solicitante, generalmente estoy de acuerdo con usted. –

Respuesta

1

¿Hay algún motivo por el que no pueda usar la clave de identificación de los raíles y agregue manualmente un índice llamado Seat?

He visto algunos hacks solo para hacer que los rieles trabajen en bases de datos no incrementales. No creo que sea una opción. Si no recuerdo mal, así es como Rails accede a toda su funcionalidad por fila.

Honestamente, ¿cómo -sin duda- necesita ese ligero impulso en la eficiencia de ignorar la estructura de los rieles?

Creo que la verdadera respuesta es "no se puede". Activerecord tiene algunas cosas en las que no se doblegará.

+0

Estoy portando una aplicación ASP.MVC donde tenía mi lógica personalizada BLL y DAL, pero tiene sentido ahora – IceHeat

17

Para el registro, si es absolutamente necesario para hacer esto (que no debería suceder a menudo), aquí es la manera de hacer una clave principal no autoincremental con el DSL migración Rieles:

create_table(:table_name, :id => false) do |t| 
    t.integer :id, :options => 'PRIMARY KEY' 
end 

que la voluntad trabajo para MySQL de todos modos, si su base de datos utiliza una sintaxis diferente para especificar una clave primaria, reemplace :options => 'PRIMARY KEY' con lo que sea.

+1

Tenga en cuenta que esto todavía tiene algunos problemas, porque Rails trata mágicamente el nombre id. Si bien rompe las convenciones de nomenclatura, en términos de tener que codificar cosas, es preferible nombrar el campo de la clave principal algo que no sea id. –

+1

Si le doy otro nombre, ¿debería cambiar mi route.rb, Cancan 'load_resource', etc.? Gracias ~ – lulalala

2

Esta pregunta es de 3 años de edad, pero en caso que alguien se está preguntando 3 años más tarde, como yo, todo lo que hacen es "change_column" en el caso de la mesa ya está creado:

change_column(:table_name, :id, :integer, :null => false) 

Esto debería funcionar en Rails 2.xy 3.x.

O

0

No decir que es una buena idea, pero aquí es cómo lo hice por SQLite3 - acaba de sustituir a la SQLiteAdapter con adaptador de tu DB - que podría hacer este limpiador/corto con una llamada a define_method

class AbstractAdapter 
end 

module ActiveRecord 
    module ConnectionAdapters 
    class SQLiteAdapter < AbstractAdapter 
     def supports_autoincrement? 
     false 
     end 
    end 
    end 
end 

<then you migration> 

o

class SomeMigration < ActiveRecord::Migration 
    def change 
    create_table :table do |t| 
     ActiveRecord::ConnectionAdapters::SQLiteAdapter.send :define_method, :supports_autoincrement? do false end 
     t.integer etc 
    end 
    end 
end 

por supuesto, sólo cambia el adaptador para otra db de

Cuestiones relacionadas