Actualizar:
Este problema no se exploró correctamente. El problema real está dentro render :json
.
El primer pegado de código en la pregunta original producirá el resultado esperado. Sin embargo, todavía hay una salvedad. Vea este ejemplo:
render :json => current_user
NO es lo mismo que
render :json => current_user.to_json
Es decir, render :json
no llamará automáticamente al to_json
método asociado con el objeto Usuario. De hecho , si to_json
se anula en el User
modelo, render :json => @user
generará lo que se ArgumentError
describe a continuación.
resumen
# works if User#to_json is not overridden
render :json => current_user
# If User#to_json is overridden, User requires explicit call
render :json => current_user.to_json
Todo esto me parece una tontería. Esto parece decirme que en render
realidad no está llamando Model#to_json
cuando :json
se especifica el tipo . ¿Alguien puede explicar lo que realmente está pasando aquí?
Cualquier genio que pueda ayudarme con esto probablemente pueda responder a mi otra pregunta: Cómo crear una respuesta JSON combinando @ foo.to_json (opciones) y @ bars.to_json (opciones) en Rails
Pregunta original:
He visto algunos otros ejemplos en SO, pero ninguno hace lo que estoy buscando.
Lo estoy intentando:
class User < ActiveRecord::Base
# this actually works! (see update summary above)
def to_json
super(:only => :username, :methods => [:foo, :bar])
end
end
Me estoy poniendo ArgumentError: wrong number of arguments (1 for 0)
en
/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json
¿Algunas ideas?
fuente
username
,foo
obar
espera argumentos?username
no es un método y unfoo
ybar
no requieren métodos. Actualicé mi pregunta para mostrar dónde está ocurriendo el error.Respuestas:
Obtiene
ArgumentError: wrong number of arguments (1 for 0)
porqueto_json
debe anularse con un parámetro, eloptions
hash.Explicación más larga de
to_json
,as_json
y renderizado:En ActiveSupport 2.3.3,
as_json
se agregó para abordar problemas como el que ha encontrado. La creación del json debe estar separada de la representación del json.Ahora, en cualquier momento
to_json
se llama a un objeto,as_json
se invoca para crear la estructura de datos y luego ese hash se codifica como una cadena JSON usandoActiveSupport::json.encode
. Esto sucede para todos los tipos: objeto, numérico, fecha, cadena, etc. (consulte el código de ActiveSupport).Los objetos ActiveRecord se comportan de la misma manera. Existe una
as_json
implementación predeterminada que crea un hash que incluye todos los atributos del modelo. Debe anularas_json
en su modelo para crear la estructura JSON que desee .as_json
, al igual que el anteriorto_json
, toma una opción hash donde puede especificar atributos y métodos para incluirlos declarativamente.En su controlador,
render :json => o
puede aceptar una cadena o un objeto. Si es una cadena, se pasa a través del cuerpo de la respuesta, si es un objeto,to_json
se llama, que se activaas_json
como se explicó anteriormente.Por lo tanto, siempre que sus modelos estén representados correctamente con
as_json
anulaciones (o no), el código de su controlador para mostrar un modelo debería verse así:La moraleja de la historia es: Evite llamar
to_json
directamente, permitarender
que lo haga por usted. Si necesita modificar la salida JSON, llameas_json
.fuente
as_json
. Como puede ver en los documentos de ActiveRecord :: Serialization ( api.rubyonrails.org/classes/ActiveRecord/… ), hay muy poca (ninguna) documentación para esto. Lo intentaré :)as_json
médicos! Gracias de nuevo :)Si tiene problemas con esto en Rails 3, anule en
serializable_hash
lugar deas_json
. Esto también obtendrá su formato XML gratis :)Esto me tomó una eternidad averiguarlo. Espero que ayude a alguien.
fuente
serializable_hash
? Cuando lo uso, cambia mi salida xml posterior de envolver el objeto con su nombre (por ejemplo, "cita" para un objeto de cotización ") a, en cambio, siempre envolverlo con" <hash> ".to_xml
Para las personas que no quieren ignorar las opciones de los usuarios pero que también agregan las suyas:
Espero que esto ayude a alguien :)
fuente
options
hash de= {}
forma predeterminada, por lo que no es necesario al llamarNo anule to_json, sino as_json. Y desde as_json llama lo que quieras:
Prueba esto:
fuente
as_json
solo para ActiveResource?render :json => current_user
, obtengo el resultado predeterminado esperado (todos los atributos delUser
modelo en formato JSON). Cuando agrego elas_json
método a miUser
modelo e intento lo mismo,