There seems to be a limitation on how one can use the options hash with to_json. Take this example: * render :json => { :results => @posts.to_json(:only => [:title] ) } * You don''t end up with what you want; instead of results being an array of posts, results becomes an escaped string. I recently put a patch on lighthouse that would cover this specific case but after some further thought, I think a more general solution is in order. Suppose to_json rather than returning a String instead returned a JSONString. We could then create an encoder for JSONString which does not re-escape itself when to_json is called on it. You would then be free to do something like the example above and it would all "just work". You''d also be able to pass different options to different AR collections being returned in the same result. Are there any other thoughts out there on this? -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
On Tue, Feb 2, 2010 at 8:09 AM, Stephen <sblackstone@gmail.com> wrote:> There seems to be a limitation on how one can use the options hash with > to_json. Take this example: > > render :json => { :results => @posts.to_json(:only => [:title] ) } > > You don''t end up with what you want; instead of results being an array of > posts, results becomes an escaped string. I recently put a patch on > lighthouse that would cover this specific case but after some further > thought, I think a more general solution is in order. > > Suppose to_json rather than returning a String instead returned a > JSONString. We could then create an encoder for JSONString which does not > re-escape itself when to_json is called on it. > > You would then be free to do something like the example above and it would > all "just work". You''d also be able to pass different options to > different AR collections being returned in the same result. > > Are there any other thoughts out there on this?The problem is that to_json is really the wrong API for providing custom JSON output. We nearly always want to transform an object into *JSON-encodable primitives*. Not into a JSON string. So we split the brittle to_json API into as_json and to_json. Rather than implement to_json to return a string, implement as_json to return a JSON-encodable primitive. to_json converts the object using as_json before encoding. class Foo # new way: return a JSON representation def as_json { :foo => bar } end # old way: return a JSON string def to_json(*ugly_internal_options) { :foo => bar }.to_json(*ugly_internal_options) end end In short, this allows you to do render :json => { :results => @posts.as_json(:only => [:title] ) } jeremy -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Ok, that makes sense. Is this rails 3+ only? while the method appears to exist in rails 2.3.5, it thoroughly ignores my options hash. On Tue, Feb 2, 2010 at 11:26 AM, Jeremy Kemper <jeremy@bitsweat.net> wrote:> On Tue, Feb 2, 2010 at 8:09 AM, Stephen <sblackstone@gmail.com> wrote: > > There seems to be a limitation on how one can use the options hash with > > to_json. Take this example: > > > > render :json => { :results => @posts.to_json(:only => [:title] ) } > > > > You don''t end up with what you want; instead of results being an array of > > posts, results becomes an escaped string. I recently put a patch on > > lighthouse that would cover this specific case but after some further > > thought, I think a more general solution is in order. > > > > Suppose to_json rather than returning a String instead returned a > > JSONString. We could then create an encoder for JSONString which does > not > > re-escape itself when to_json is called on it. > > > > You would then be free to do something like the example above and it > would > > all "just work". You''d also be able to pass different options to > > different AR collections being returned in the same result. > > > > Are there any other thoughts out there on this? > > The problem is that to_json is really the wrong API for providing > custom JSON output. > > We nearly always want to transform an object into *JSON-encodable > primitives*. Not into a JSON string. > > So we split the brittle to_json API into as_json and to_json. Rather > than implement to_json to return a string, implement as_json to return > a JSON-encodable primitive. to_json converts the object using as_json > before encoding. > > class Foo > # new way: return a JSON representation > def as_json > { :foo => bar } > end > > # old way: return a JSON string > def to_json(*ugly_internal_options) > { :foo => bar }.to_json(*ugly_internal_options) > end > end > > In short, this allows you to do > > render :json => { :results => @posts.as_json(:only => [:title] ) } > > jeremy > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com<rubyonrails-core%2Bunsubscribe@googlegroups.com> > . > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
This is Rails 2.3.6+ (pending release). You can freeze to the 2-3-stable branch to use it now. jeremy On Tue, Feb 2, 2010 at 12:00 PM, Stephen <sblackstone@gmail.com> wrote:> Ok, that makes sense. Is this rails 3+ only? while the method appears to > exist in rails 2.3.5, it thoroughly ignores my options hash. > > > On Tue, Feb 2, 2010 at 11:26 AM, Jeremy Kemper <jeremy@bitsweat.net> wrote: >> >> On Tue, Feb 2, 2010 at 8:09 AM, Stephen <sblackstone@gmail.com> wrote: >> > There seems to be a limitation on how one can use the options hash with >> > to_json. Take this example: >> > >> > render :json => { :results => @posts.to_json(:only => [:title] ) } >> > >> > You don''t end up with what you want; instead of results being an array >> > of >> > posts, results becomes an escaped string. I recently put a patch on >> > lighthouse that would cover this specific case but after some further >> > thought, I think a more general solution is in order. >> > >> > Suppose to_json rather than returning a String instead returned a >> > JSONString. We could then create an encoder for JSONString which does >> > not >> > re-escape itself when to_json is called on it. >> > >> > You would then be free to do something like the example above and it >> > would >> > all "just work". You''d also be able to pass different options to >> > different AR collections being returned in the same result. >> > >> > Are there any other thoughts out there on this? >> >> The problem is that to_json is really the wrong API for providing >> custom JSON output. >> >> We nearly always want to transform an object into *JSON-encodable >> primitives*. Not into a JSON string. >> >> So we split the brittle to_json API into as_json and to_json. Rather >> than implement to_json to return a string, implement as_json to return >> a JSON-encodable primitive. to_json converts the object using as_json >> before encoding. >> >> class Foo >> # new way: return a JSON representation >> def as_json >> { :foo => bar } >> end >> >> # old way: return a JSON string >> def to_json(*ugly_internal_options) >> { :foo => bar }.to_json(*ugly_internal_options) >> end >> end >> >> In short, this allows you to do >> >> render :json => { :results => @posts.as_json(:only => [:title] ) } >> >> jeremy >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Ruby on Rails: Core" group. >> To post to this group, send email to rubyonrails-core@googlegroups.com. >> To unsubscribe from this group, send email to >> rubyonrails-core+unsubscribe@googlegroups.com. >> For more options, visit this group at >> http://groups.google.com/group/rubyonrails-core?hl=en. >> > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.