ccocchi / rabl-rails

Rails 4.2+ templating system with JSON, XML and Plist support.
MIT License
209 stars 51 forks source link

undefined method 'collection' #10

Closed sergeych closed 11 years ago

sergeych commented 11 years ago

Sometimes - not always:

Started GET "/api/collections" for 95.25.169.19 at 2012-10-22 13:50:53 +0000 Processing by Api::CollectionsController#index as HTML Rendered api/collections/index.rabl (3.0ms) Failure: undefined method collection' for #<Collection:0x00000004f57d38> Class: NoMethodError /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activemodel-3.2.8/lib/active_model/attribute_methods.rb:407:inmethod_missing' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.8/lib/active_record/attribute_methods.rb:149:in method_missing' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:56:inblock in render_resource' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:51:in each' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:51:ininject' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:51:in render_resource' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:97:inblock in render_collection' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:97:in map' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:97:inrender_collection' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:30:in render' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/library.rb:18:inget_rendered_template' /media/data1/www-data/mydreamboardapp.com/releases/20121022130156/app/views/api/collections/index.rabl:2:in `_app_views_api_collections_index_rabl__728353672390700706_51375400'

Mos of the time ir works fine.

index.rabl:

collection :@collections

extends 'api/commons/collection'

sergeych commented 11 years ago

It might be because I do have a Collection model so I use the @collections var. pity I can't change it as a i need { '"collections" : [] } result

sergeych commented 11 years ago

Looks like I worked it out by not using vars @collection and @collections in the controller. It works already a few hours but it certainly sucks. I'd love to have it fixedm but onsuch a schedule so can't ebough time to investigate... Worst of all, it means that we can get same problems when using methods/vars in our models/controller, like @child, bode, @attribute?

ccocchi commented 11 years ago

What's inside your 'api/commons/collection' ? Because the problem seems not to be the ivar name @collections, but that you are trying to call a method #collection on your Collection model...

sergeych commented 11 years ago

Actually I don't have Collection#collection anywhere. Though I have it in other models, say Item#collection. Anyway:

api/commons/collection:

attributes :id, :name
node(:cover_url) { |c|
    c.cover(:medium)
}

I've got a strange workaround that works for now: i do not use @collection && @collections in neither in the conroller nor in views, i have rewritten them to:

child(:@cc => :collections) {
    extends 'api/commons/collection'
}

and collections/show (that sometimes gave same error) as:

child(:@c => :collection) do
    extends 'api/commons/collection'

    child(:@items) {
        extends 'api/commons/item'
    }

end

and it still works. Though its ugly :(

ccocchi commented 11 years ago

I wrote a test with a Collection model, and it works fine. Could you come up with a small example project that reproduces the bug ?

sergeych commented 11 years ago

This version did not work (actually, it works some time, then fails, after some point it returns above mentioned error. It could, though^ serve hundreds request just fine first, so it was not easy to track and would not be easy for you to reproduce:

class Api::CollectionsController < Api::ApplicationController

before_filter :load_collection, :except => [:index]

def index @collection = Collection.all

rabl: collection :@collection

end

def show

rabl: object :@collection

end

private

def load_collection @collection = Collection.find(params[:id]) @items = @collection.items.order('id desc').limit(300) end

end

Th workaround that works:

class Api::CollectionsController < Api::ApplicationController

before_filter :load_collection, :except => [:index] def index @cc = Collection.all

rabl child(:@cc => :collections) {

end

def show

Rabl: child(:@c => :collection) do

end

private

def load_collection @c = Collection.find(params[:id]) @items = @c.items.order('id desc').limit(300) end

end

Sorry I just have no time now to extract the sample project, would do it after release that is less than two weeks ahead. But for sure it got fixed by this small change. It is not because of the Collection model as I though, this fix yields that only @collection/@collections vars/attributes in the controller context caused the problem. And certainly it hash a random natude: some requests are served ke, some got broken. It looks like that rabl

collection :@collection

sometimes return my @collection attribute from the controller's context, and sometimes a valid rabl object whatever it is ;) Ot something very close, as the key was "collection :@collection" fix.

23.10.2012, â 14:04, Christopher Cocchi-Perrier notifications@github.com íàïèñàë(à):

I wrote a test with a Collection model, and it works fine. Could you come up with a small example project that reproduces the bug ?

— Reply to this email directly or view it on GitHub.

sergeych commented 11 years ago

Worst of all I've got another clash like this: Controller var @item somehow sometimes hide template api/commons/item. After 30m of trying to find the reason os some strange error about 'missing item attribute' - and I never used one - the problem dissapears on the exactly same code :(

ccocchi commented 11 years ago

Are you using the cache_templates option or a multithreaded application?

sergeych commented 11 years ago

no. I use nginx+passenger in the single threaded mode. rails 3.2.8, ruby 1.9.3

Are you using the cache_templates option or a multithreaded application?

— Reply to this email directly or view it on GitHub.

sergeych commented 11 years ago

The log of the exception:

Started GET "/api/items/10" for 128.72.171.138 at 2012-10-31 04:09:16 +0000 Processing by Api::ItemsController#show as JSON Parameters: {"id"=>"10", "item"=>{}} 12/10/31 04:09:16 : Api::ItemsController : Authtoken is taken from headers Rendered api/items/show.rabl (9.9ms) Failure: undefined method item' for #<Item:0x00000005b1fe68> Class: NoMethodError /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activemodel-3.2.8/lib/active_model/attribute_methods.rb:407:inmethod_missing' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activerecord-3.2.8/lib/active_record/attribute_methods.rb:149:in method_missing' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:56:inblock in render_resource' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:51:in each' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:51:ininject' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:51:in render_resource' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/renderers/base.rb:31:inrender' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/rabl-rails-0.2.2/lib/rabl-rails/library.rb:18:in get_rendered_template' /media/data1/www-data/mydreamboardapp.com/releases/20121030163245/app/views/api/items/show.rabl:2:in_app_views_api_items_show_rabl__1357555209293645053_33622280' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/template.rb:145:in block in render' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activesupport-3.2.8/lib/active_support/notifications.rb:125:ininstrument' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/template.rb:143:in render' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/template_renderer.rb:47:inblock (2 levels) in render_template' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/abstract_renderer.rb:38:in block in instrument' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activesupport-3.2.8/lib/active_support/notifications.rb:123:inblock in instrument' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activesupport-3.2.8/lib/active_support/notifications/instrumenter.rb:20:in instrument' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/activesupport-3.2.8/lib/active_support/notifications.rb:123:ininstrument' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/abstract_renderer.rb:38:in instrument' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/template_renderer.rb:46:inblock in render_template' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/template_renderer.rb:54:in render_with_layout' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/template_renderer.rb:45:inrender_template' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/template_renderer.rb:18:in render' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/renderer.rb:36:inrender_template' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_view/renderer/renderer.rb:17:in render' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/abstract_controller/rendering.rb:110:in_render_template' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_controller/metal/streaming.rb:225:in _render_template' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/abstract_controller/rendering.rb:103:inrender_to_body' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_controller/metal/renderers.rb:28:in render_to_body' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_controller/metal/compatibility.rb:50:inrender_to_body' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/abstract_controller/rendering.rb:88:in render' /var/www-data/mydreamboardapp.com/shared/bundle/ruby/1.9.1/gems/actionpack-3.2.8/lib/action_controller/metal/rendering.rb:16:inrender' Completed 500 Internal Server Error in 90ms (Views: 0.4ms | ActiveRecord: 0.7ms)

I never use 'item' as an attribute. I use it as object. In the controller it is set like:

def load_item
  @item = Item.find params[:id] || params[:item_id]
end

In the view:

object :@item

extends 'api/commons/item'

child(:@marks) do
    extends 'api/commons/mark'
end
sergeych commented 11 years ago

Worst of all, it appears after some considerable radnom time and dissapear with application restart. For some time. then it appears again. I have a week to production - probably would temporaily switch to slow rable until this thing will be fixed. thanks in advance. If the problem persists - that means, not in you gem, I'll close the issue.

ccocchi commented 11 years ago

I've used this gem in production for months now and I never ran in this problem. The randomness of this make me think of 2 issues : multithreading or caching problems. Are you sure you've tried with the cache_templates options set to false ?

sergeych commented 11 years ago

Actually, I didn't touch settings at all. I'll add it right now and uncomment cache_templates and see what will happen. Actually, it might be interference of rails internals and ruby version. Maybe even some bug in ruby. Well, lets see whether default settings will help it I'll set 'em by hand.

Might it be because I had no

config/initializers/rabl_rails.rb

RablRails.configure do |config|

These are the default

config.cache_templates = true

config.include_json_root = true

config.json_engine = :oj

config.xml_engine = 'LibXML'

config.use_custom_responder = false

# config.default_responder_template = 'show'

end block at all?

Thanks again!

31.10.2012, â 12:27, Christopher Cocchi-Perrier notifications@github.com íàïèñàë(à):

I used this gem in production for months now and I never ran in this problem. The randomness of this make me think of 2 issues : multithreading or caching problems. Are you sure you set the cache_templates options to true ?

— Reply to this email directly or view it on GitHub.

ccocchi commented 11 years ago

Try to set cache_templates to false.

When it is enable, it will cache the compiled source according to the path of the template. For example if you render views/items/show, it will used items/show as cache key so next time you render it or use extends "items/show", it will use the compiled source directly.

Maybe there are cache key collisions with your setup

ccocchi commented 11 years ago

Any news concerning this issue?

sergeych commented 11 years ago

Still the same. Works few hours then something happens and it fails on every request since then. Bad luck :(

Sergey.

06.11.2012, â 2:42, Christopher Cocchi-Perrier notifications@github.com íàïèñàë(à):

Any news concerning this issue?

— Reply to this email directly or view it on GitHub.

ccocchi commented 11 years ago

I added a test with collection keywords to ensure there is no problem.

I also tried to reproduce your problem but without success. I'm closing this issue for now, since others website running with rabl-rails aren't encountering it.

I would gladly reopen it if you can reproduce the issue in a basic rails app. Thanks for your feedback anyway :heart: