Thank you for the quick response, Jeremy.

Looks like you were right. I believe it is the association_proxies plugin. 
Sorry about the formatting.

Both of the solutions you've offered worked perfectly. Each gave the output 
I was expecting.

Thank you, again.
-Patrick

On Monday, May 2, 2016 at 10:37:18 AM UTC-4, Jeremy Evans wrote:
>
> On Sunday, May 1, 2016 at 10:35:24 PM UTC-7, Patrick Kuykendall wrote:
>>
>> Hello,
>>
>> I'm running into a little hiccup with the json_serializer plug-in. If I 
>> try to include an association that is an array, the to_json call doesn't 
>> process the items in the array, just the array itself. I added the 
>> activesupport fixes you mention in the documentation, but I'm still having 
>> this issue.
>>
>> Something like this should be able to reproduce it:
>>
>> class User < Sequel::Model(DB[:users])
>>   one_to_many :addresses
>> end
>>
>> class Address < Sequel::Model(DB[:addresses])
>> end
>>
>> User.first.to_json(
>>     only: [:first_name, :last_name],
>>     include: {
>>       addresses: { only: [:line_1, :line_2, :city, :state, :zip_code] } 
>>     }
>>   )
>> #=> {first_name: 'John', last_name: 'Doe', addresses: [{address_id: 1, 
>> address_type_id: 1, line_1: 'XXX' line_2: nil, city 'XXX', state: 'XXX', 
>> zip_code: '12345', created_on: 2016-05-01T01:30:00, updated_on: nil, 
>> deleted_on: nil}]}
>>
>>
>> I dove into it a little and I found that InstanceMethods#to_json performs 
>> a check to see if the included association is an Array. It seems this isn't 
>> catching for me, and it's processing the array object as a whole.
>>
>> Here's the section: [direct link](
>> https://github.com/jeremyevans/sequel/blob/master/lib/sequel/plugins/json_serializer.rb#L303
>> )
>>
>> cols.each{|c| h[c.to_s] = get_column_value(c)}
>> if inc = opts[:include]
>>   if inc.is_a?(Hash)
>>     inc.each do |k, v|
>>     v = v.empty? ? [] : [v]
>>     h[k.to_s]  = case objs = send(k)
>>       when 'Array'
>>         objs.map{|obj| Literal.new(Sequel.object_to_json(obj, *v))}
>>       else
>>         Literal.new(Sequel.object_to_json(objs, *v))
>>       end
>>     end
>>   else
>>     Array(inc).each{|c| h[c.to_s] = send(c)}
>>   end
>> end
>>
>> I was able to have it properly render the objects contained in the array 
>> with this. (Pardon the dirty hack, I was just testing it out)
>>
>> cols.each{|c| h[c.to_s] = get_column_value(c)}
>> if inc = opts[:include]
>>   if inc.is_a?(Hash)
>>     inc.each do |k, v|
>>     v = v.empty? ? [] : [v]
>>     objs = send(k)
>>     h[k.to_s] = case objs.class.to_s
>>       when 'Array'
>>         objs.map{|obj| Literal.new(Sequel.object_to_json(obj, *v))}
>>       else
>>         Literal.new(Sequel.object_to_json(objs, *v))
>>       end
>>     end
>>   else
>>     Array(inc).each{|c| h[c.to_s] = send(c)}
>>   end
>> end
>>
>> Let me know if I might be doing something wrong here.
>> Thank you.
>>
>
> Unfortunately, this isn't a self contained example, so at most I can give 
> an educated guess.  From the change your making it looks like you are just 
> changing the case statement (please use a diff in the future to make the 
> change more obvious).  The only situation I can think of where that would 
> solve the problem is if you were using the association_proxies plugin, in 
> which case the association method returns a proxy and not an array, but 
> calling class on the object will return Array.
>
> I think one possible way to get what you want without modifying the 
> json_serializer plugin would be to preprocess the addresses:
>
> u = User.first
> u.addresses.each{|a| a.json_serializer_opts(only: [:line_1, :line_2, 
> :city, :state, :zip_code])}
> u.to_json(only: [:first_name, :last_name], include: :addresses)
>
> In terms of modifying the json_serializer plugin, we could see if the 
> :include value is also an association, and if so if the association returns 
> an array, falling back to the current code for detecting arrays if the 
> value is not an association.  Something like:
>
> diff --git a/lib/sequel/plugins/json_serializer.rb 
> b/lib/sequel/plugins/json_serializer.rb
> index c953295..8215548 100644
> --- a/lib/sequel/plugins/json_serializer.rb
> +++ b/lib/sequel/plugins/json_serializer.rb
> @@ -300,8 +300,16 @@ module Sequel
>              if inc.is_a?(Hash)
>                inc.each do |k, v|
>                  v = v.empty? ? [] : [v]
> -                h[k.to_s] = case objs = send(k)
> -                when Array
> +
> +                objs = send(k)
> +
> +                is_array = if r = model.association_reflection(k)
> +                  r.returns_array?
> +                else
> +                  objs.is_a?(Array)
> +                end
> +
> +                h[k.to_s] = if is_array
>                    objs.map{|obj| Literal.new(Sequel.object_to_json(obj, 
> *v))}
>                  else
>                    Literal.new(Sequel.object_to_json(objs, *v))
>
> Can you try that out and see if it works for you?
>
> Thanks,
> Jeremy
>

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to