'Columna ‘id’ no existe' error al intentar asociar un rol con un usuario que utiliza los carriles-autorización

StackOverflow https://stackoverflow.com/questions/689496

  •  22-08-2019
  •  | 
  •  

Pregunta

Estoy explorando los carriles por primera vez y tratando de añadir un poco de seguridad basada en roles bastante sencillo de mi aplicación de prueba. Algunos googlear parecía indicar carriles-autorización es el camino a seguir para esta. Seguí el README y todo parecía ir bien, pero ahora estoy tratando de asociar un User con un Role y falla. He aquí el fragmento de mi sesión de script/console:

>> u = User.find(:first)
=> #<User id: 1, login: "cwhit", name: "", email: "cwhitfield@unica.com", crypted_password: "7ac064547fb8992e8e53e936df31657a40f9c5af", salt: "56671492059f8e40eb3d509940944aaba31ebc72", created_at: "2009-03-26 18:06:04", updated_at: "2009-03-26 18:06:04", remember_token: nil, remember_token_expires_at: nil>
>> r = Role.find(:first)
=> #<Role id: 1, name: "ProjectManager", authorizable_type: nil, authorizable_id: nil, created_at: "2009-03-27 11:02:35", updated_at: "2009-03-27 11:02:35">
>> u.has_role r
ActiveRecord::StatementInvalid: PGError: ERROR:  column "id" does not exist
LINE 1: ....546623', '2009-03-27 11:42:16.546623', 5, 1) RETURNING "id"
                                                                   ^
: INSERT INTO "roles_users" ("created_at", "updated_at", "role_id", "user_id") VALUES('2009-03-27 11:42:16.546623', '2009-03-27 11:42:16.546623', 5, 1) RETURNING "id"

¿Estoy haciendo algo tonto, o se trata de un problema conocido? He encontrado esencialmente el mismo error en una pregunta en el grupo de Google para el plugin rails-authorization, pero no había ninguna solución proporcionada.

Aquí está mi configuración básica:

  • OS X
  • Rails 2.3.2
  • PostgreSQL
  • Plugins:
    • reparador-autenticación
    • carriles-autorización
¿Fue útil?

Solución

Trate de instalar el composite_primary_keys gema (enlace) y añadir el siguiente al controlador RolesUser:

set_primary_keys :user_id, :role_id

Dado que no hay ningún campo ID para esa tabla (y no tiene que ser), la clave principal se convierte en (user_id, role_id) que se pueden agregar a la base de datos con

 ALTER TABLE roles_users ADD PRIMARY KEY (user_id, role_id);

Esto resolvió el problema en mi caso, lo que parece ser Postgres-específica.

Otros consejos

encontré con el mismo problema con los modelos en los que estaba usando una clave principal que no sea 'id'. Resulta que me había olvidado de declarar que en la definición de clase modelo usando "set_primary_key". Tal vez lo que necesita hacer algo como esto:

class CulpritClass < ActiveRecord::Base

  set_primary_key :key_field_you_want

end

Simplemente usé dos declaraciones de clave principal

set_primary_key :user_id

set_primary_key :role_id

Esto funcionó para mis propósitos, pero tenga en cuenta que devuelve (en el sql al menos) la segunda clave principal que se defina. En este caso, sería el ROLE_ID del objeto.

Yo tenía el mismo problema, pero en destruyo (de los roles). Probé la joya composite_primary_keys pero encontré que rompió otras cosas en Rails 2.3.4. Específicamente, causó asociación Rails :belongs_to para generar el mal atribuye id en esta situación:

   belongs_to :inviter, :class_name => 'User'

Se generando user_id como el nombre del atributo en lugar de inviter_id.

La última solución fue añadir una columna de ID de roles_users. Puesto que ya tenía una mesa roles_users sin llave sustituta que tenía que hacer esta migración lil:

  class AddIdToRolesUsers < ActiveRecord::Migration
    def self.up

      # create new table the way it should be (_with_ a traditional Rails id column)
      create_table :x_roles_users do |t|
        t.belongs_to :role
        t.belongs_to :user
        t.timestamps
      end

      execute 'insert into x_roles_users (user_id, role_id, created_at, updated_at) select * from roles_users'

      drop_table :roles_users

      rename_table :x_roles_users, :roles_users
    end

    def self.down
      remove_column :roles_user, :id
    end
  end
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top