nesquena / rabl

General ruby templating with json, bson, xml, plist and msgpack support
http://blog.codepath.com/2011/06/27/building-a-platform-api-on-rails/
MIT License
3.65k stars 335 forks source link

Using a hash as the data object does not seem to work. #21

Closed kimptoc closed 13 years ago

kimptoc commented 13 years ago

Hi,

I am probably doing this wrong, but I have a method that wants to return a collection and a status, so I am making my data object sort of like this:

@thing = {:foo => "bar", :pop => 123}

So, my rabl template is

    attributes :foo, :pop

Hoping to get { "foo" : "bar", "pop" :123}

But was getting this under last night's version: { "pop":"bar", "pop":123}

Today I get an error: undefined method `to_html' for #<Rabl::Engine:0x1075c0730>

Perhaps I should be using the "object false" route...

Thanks, Chris

PS Tried to add tests/fix it - seems that the problem is the attribute method can be passed a hash of options and its confusing the object hash as options:

https://github.com/kimptoc/rabl/commit/dc3be6eba6389998614f7cb846240aebcc2062ef

nesquena commented 13 years ago

I never considered using a hash as the object, interesting idea. I always used a class (ORM) record as the object. I guess I don't see a reason a Hash couldn't be made to work but not surprising it doesn't. There are a few assumptions I made about the object right now and one of them is that the object responds to the "valid?" method and that it has dot notations to access attributes.

Here's how I would achieve what you want for now:

object false
node(:foo) { "bar" }
node(:pop) { 123 }

or if its a nested hash:

object false
node(:thing) { @thing }

I have to give this some thought, this is a use case I never considered supporting.

nesquena commented 13 years ago

Also as for the undefined methodto_html' for #Rabl::Engine:0x1075c0730` it looks like you are trying to use RABL during an HTML request (not a json or xml request). You probably shoudn't allow the action to respond to HTML or have an alternate erb or haml template for that case...

kimptoc commented 13 years ago

Hi,

Thanks for the feedback - will try what you suggest.

I tried creating a local object like this:

class Thing
    attr_accessor :foo, :pop
    def initialize(a,b)
      @foo =a
      @pop =b
    end

  end

So the controller did this:

@thing2 = Thing.new("boo",987)

And template is this:

object @thing2
attributes :foo, :pop

Getting 'null' response (when I specify the format).

On the to_html stuff, yesterday I got away without it - not sure how. Wonder if there is a way to make json the default format.

Thanks, Chris

kimptoc commented 13 years ago

Hi,

Just to say your suggestion with the "object false" does the job - and is clearer in my controller, so I prefer it - the hash was a contrived object to get the data to the view - so better to not have it :)

Thanks, Chris

nesquena commented 13 years ago

@kimptoc the to_html error comes from this change yesterday: ed9ec55b5707908ced0d2d4f0007e15957513216 in which I detect the request format if theres no explicit format. I will have to fix it by disallowing html as the format I think and default to json.

As for the Thing record, try this for fun:

class Thing < Struct.new(:foo, :pop)
   def initialize(h)
     super *h.values_at(*self.class.members.map {|s| s.intern})
   end

  def valid?; true; end
end

and

@thing2 = Thing.new(:foo => "boo", :pop => 987)

Can you tell me if that works?

nesquena commented 13 years ago

@kimptoc Okay, I am actually going to close this for now, I have never had the need to use a hash as the object. I don't think I will in the future either. In the case of constructing a response from scratch I would go with the object false approach :) If you or someone else finds this issue, I am not against the idea if someone else would like to patch it in with a pull request. I will fix the "to_html" issue tho soon. Thanks!

kimptoc commented 13 years ago

Hi,

The Thing suggestion works just fine and yes, please close it - was going to suggest that.

Regards, Chris

nesquena commented 13 years ago

@kimptoc Fixed the 'to_html' issue here, can you confirm? 7f97b7e60aee3c274635f7d2aeafb32a13048951

kimptoc commented 13 years ago

Hey @nesquena - perfect, works like a charm :)

Many thanks.

nesquena commented 13 years ago

Excellent thanks man, pushing out a small gem point release.