'Columna ‘id’ no existe' error al intentar asociar un rol con un usuario que utiliza los carriles-autorización
-
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
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