Pasar valor explicitamente al campo "id"

Saludos amigos, me he visto en la necesidad de pasar un valor
explicitamente al campo id en vez de dejar que lo asigne
automaticamente(autoincrementar), en la vista he creado algo asi:

Codigo: <%= text_field :cliente,:id%>

Cuando le asigno el valor y luego intento grabar el registro, veo que
activerecord no respeta lo que puse, lo toma como nil, y en el caso que
el id sea una cadena, me da un error ya que el valor esta vacio, espero
sus sugerencias, ante todo gracias por su tiempo ;).

Ruben.

Hola Xavier, el problema es que no puedo tener un id que sea
alfanumerico, y mucho menos asignarle un valor explicito; aunque ya
comprendi el porque de ese comportamien de RoR, de exigir que el id sea
entero y autoincrementable, lo que yo me planteaba era esto:

Tengo un modelo clieente cuyo “id” es alfanumerico

class Cliente < ActiveRecord::Base; end

Sucede que mi cliente me pidio que el mismo colocaria los codigos de
productos, no queria que se autogeneraran, por lo tanto yo queria
agregar el campo “id” en las vista tanto de edicion como de nuevo
registro, por eso hacia algo asi en el partial “_form”:

<%= text_field :cliente,:id %>

El asunto viene aqui, yo necesitaba trabajar con el valor del campo
“id”, por lo tanto lo llamaba en el callback “before_save”, pero el
atributo “id”, me devuelve nil; ahora el otro problema era que no
grababa el registro luego de editarlo, tambien era porque devolvia nil
el atributo “id”.

Bueno la solucion por la que opte fue, crear otro campo con restriccion
UNIQUE e indexarlo, y guardar ahi el codigo que ingrearia el usuario, y
el capo “id” dejarlo como entero y autoincrementable.

Ahora yo me pregunto como podria hacer en el caso que trabaje con una
base de datos ya generada y en produccion con otro sistema, en donde las
claves primarias no sean enteras y muco menos autoincrementables, como
podria hacer en la necesidad de querer trabajar con el valor de la PK?

Saludos!.

El mié, 14-03-2007 a las 19:17 +0100, Xavier N. escribió:

On Mar 14, 2007, at 5:38 AM, Ruben Alexis D. wrote:

Saludos amigos, me he visto en la necesidad de pasar un valor
explicitamente al campo id en vez de dejar que lo asigne
automaticamente(autoincrementar), en la vista he creado algo asi:

Codigo: <%= text_field :cliente,:id%>

Cuando le asigno el valor y luego intento grabar el registro, veo que
activerecord no respeta lo que puse, lo toma como nil

No puedo reproducirlo ni con enteros ni con cadenas. Puedes enviar un
ejemplo minimo?

– fxn

Ruben, no luches contra los ID en rails. Usa id numericos y
autoincrementados, y luego agrega un campo de “codigo” o “nombre” o
como lo quieras llamar.

Lo unico que necesitas hacer para utilizar ese campo en los URL es lo
siguiente:

class Cliente < AR::B
def to_param
codigo
end
def self.find_by_param param
self.find_by_codigo(param) or
raise ::ActiveRecord::RecordNotFound.new(“Not found #{self.name} with
param #{param}”)
end
end

Esto hace que en tus vistas, cuando uses link_to o url_for de la
siguiente manera, se ejecute el to_param y por lo tanto codigo en
lugar de id:
<%= link_to cliente.nombre, :action => ‘show’, :id => cliente %> #
Notese el uso de ‘cliente’ a secas, no ‘cliente.id’

Luego tu controlador seria:

class ClienteController
def show
@cliente = Cliente.find_by_param(params[:id])
end
end

O algo similar.

On Mar 15, 2007, at 6:17 AM, Ruben Alexis D. wrote:

Sucede que mi cliente me pidio que el mismo colocaria los codigos de
productos, no queria que se autogeneraran,

El asunto viene aqui, yo necesitaba trabajar con el valor del campo
“id”, por lo tanto lo llamaba en el callback “before_save”, pero el
atributo “id”, me devuelve nil; ahora el otro problema era que no
grababa el registro luego de editarlo, tambien era porque devolvia nil
el atributo “id”.

Este comportamiento no lo entiendo. El parametro “id” se ignora si
viniera en el hash que se pasa a Model.new(), o update_attributes(),
pero si manualmente asignas un id con model.id = 45 a la hora de
crear el registro en mis pruebas con MySQL funciona (asumiendo que el
45 este libre). Me gustaria saber un poco mas de esto si tuvieras un
momento para entender por que pasa.

Bueno la solucion por la que opte fue, crear otro campo con
restriccion
UNIQUE e indexarlo, y guardar ahi el codigo que ingrearia el
usuario, y
el capo “id” dejarlo como entero y autoincrementable.

Esta solucion es lo suyo si es posible. No es que tecnicamente sea
necesaria, pero si el usuario puede entrar codigos de producto en tu
aplicacion esta bien ordenado el tenerlos en su propia columna y
ofrecer interfaz a traves de ella, pero tener un campo ID privado
como llave primaria. En el Agile lo recomiendan en una discusion creo
que es sobre (no) usar ISBNs como llave primaria.

Ahora yo me pregunto como podria hacer en el caso que trabaje con una
base de datos ya generada y en produccion con otro sistema, en
donde las
claves primarias no sean enteras y muco menos autoincrementables, como
podria hacer en la necesidad de querer trabajar con el valor de la PK?

En principio con tu propia gestion a mano con self.id = “foo” en
before_create deberia funcionar, configurando el nombre de columna
con set_primary_key si fuera necesario (en tal caso se sigue usando
self.id).

– fxn