Me gustaría definir una clave única para los registros basados en 2 columnas : ‘id’ y ‘lenguaje’

para permitir que el usuario envía las siguientes cadenas :
id=1 language=es el valor=blabla inglés
id=1 language=fr valor=blabla francés

Traté de usar set_primary_key y también add_index pero no funcionó ( add_index :palabras, [«id», «language_id»], :unique => verdadero )

Tengo el siguiente modelo :

class Word < ActiveRecord::Base
  belongs_to :dictionnary
  belongs_to :language

  attr_accessible :lang, :rev, :value, :dictionnary_id, :language_id

  validates :value, :uniqueness => true

end  

y este

class Language < ActiveRecord::Base
    has_many :words

    attr_accessible :lang
end
  • si la palabra pertenece a una Lengua, por qué usted necesita para almacenar el lang con ella? Usted sólo puede delegar en el Modelo de Lenguaje. Lo que se dice que será la lucha de los raíles. Sólo quiero usar la clave de ID como clave principal. delegado :lang Idioma y no se preocupe acerca de la clave compuesta
  • de hecho, gracias. :lang viene de ald scaffilding. Necesito quitar de aquí, ya que yo uso el modelo de Lenguaje. Thx
InformationsquelleAutor Stéphane V | 2012-10-05

7 Comentarios

  1. 49

    add_index :words, ["id", "language_id"], :unique => true

    Se debe trabajar. Tal vez usted ya ha algunos no los únicos datos en su base de datos y el índice no puede ser creado? Pero (como @Doon notado va a ser redundante, ya que el id es único). Así que usted necesidad de crear la clave principal en dos columnas.

    Para definir las 2 de la columna de clave principal en los carriles de uso:

    create_table :words, {:id => false} do |t|
      t.integer :id
      t.integer :language_id
      t.string :value
      t.timestamps
    end
    execute "ALTER TABLE words ADD PRIMARY KEY (id,language_id);"

    Y establecer primary_key en su modelo con esta joya: http://rubygems.org/gems/composite_primary_keys:

    class Word < ActiveRecord::Base
        self.primary_keys = :id,:language_id
    end
    • esto agregará un índice único en la tabla para la identificación de la/language_id), pero es más que probable id será la clave primaria, y sujeto a un índice único. por lo que este índice sería redundante, ya que el id es único.
    • También es posible: validates :language_id, uniqueness: { scope: [:id] }
    • Cómo crear un combinado único (no primaria) clave basada en dos columnas? Que básicamente impide la creación de varias filas de tener los mismos valores en la columna a & columna b ..
    • Sólo quería añadir que también se puede añadir un composite_primary_key y proporcione un nombre para esa restricción con el siguiente comando: execute "ALTER TABLE words ADD CONSTRAINT contraint_name PRIMARY KEY (id, language_id)"
  2. 1

    Como dije en mi comentario va estar luchando contra los rieles si usted intenta esto, y realmente no es apoyado fuera de la caja. usted puede mirar en http://compositekeys.rubyforge.org que ofrece una forma de hacer claves primarias compuestas en rails. No lo he utilizado, ya que no he tenido una necesidad todavía (normalmente, cuando tengo algo que es clave compuesta como es sólo una tabla de combinación con ninguna clave principal y un índice único en el conjunto de pares (HABTM).

  3. 1

    Modelo

    class User < ActiveRecord::Base
      has_secure_password
      self.primary_keys = :name
    end

    Migración

    class CreateUsers < ActiveRecord::Migration
      def change
        create_table :users do |t|
          t.string :name, null: false
          t.string :emailid
          t.string :password_digest
          t.integer :locked, :default => 0
          t.text :secretquestion
          t.string :answer
    
          t.timestamps null: false
        end
        add_index :users, :name, :unique => true
      end
    end

    Obtendrá esta tabla

    Definir una clave principal único, basado en 2 columnas

  4. 0

    Dependiendo de su caso de uso que podría querer probar clave compuesta de la gema que permite definir claves primarias compuestas y también ehances ActiveRecord para tratar con este tipo de modelo (de gran ayuda para las asociaciones de este modelo o para url_for ayudantes etc.).

    Así que si usted planea en usar este modelo como cualquier otro rieles modelo de la joya va a ayudar mucho.

  5. 0

    Me enfrenté a un problema similar al migrar de un sitio a Rails. Tuve una tabla que almacena los datos de texto para cada idioma de mi sitio está disponible en así que he tenido algo como esto:

    CREATE TABLE Project_Lang(
        project_id INT NOT NULL,
        language_id INT NOT NULL,
        title VARCHAR(80),
        description TEXT,
    
        PRIMARY KEY pk_Project_Lang(project_id, language_id),
    
        FOREIGN KEY fk_Project_Lang_Project(project_id)
            REFERENCES Project(project_id)
            ON DELETE RESTRICT ON UPDATE CASCADE,
    
        FOREIGN KEY fk_Project_Lang_Language(language_id)
            REFERENCES Language(language_id)
            ON DELETE RESTRICT ON UPDATE CASCADE
    )ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_spanish_ci;

    Pero desde Rails no manejar claves primarias compuestas fuera de la caja que se vio obligado a cambiar la estructura de la tabla, así que tenía su propia clave principal:

    CREATE TABLE Project_Lang(
        project_lang_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
        project_id INT NOT NULL,
        language_id INT NOT NULL,
        title VARCHAR(80),
        description TEXT,
    
        UNIQUE INDEX(project_id, language_id),
    
        FOREIGN KEY fk_Project_Lang_Project(project_id)
            REFERENCES Project(project_id)
            ON DELETE RESTRICT ON UPDATE CASCADE,
    
        FOREIGN KEY fk_Project_Lang_Language(language_id)
            REFERENCES Language(language_id)
            ON DELETE RESTRICT ON UPDATE CASCADE
    )ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_spanish_ci;

    También he creado un índice único para las columnas que previamente hicieron la clave principal compuesta de forma que no duplicar registro se inserta. Luego, en mi Rieles modelo podía simplemente:

    self.primary_key = "project_lang_id"

    Y que hizo el truco. No es lo que yo quería, pero es mejor que la lucha contra el marco.

  6. 0

    Igual que @rogal111 dijo, pero si la clave principal ya existe, entonces usted querrá hacer esto

    ALTER TABLE sections DROP PRIMARY KEY, ADD PRIMARY KEY(id, workspace_id, section_key);

Dejar respuesta

Please enter your comment!
Please enter your name here