Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActionView::Template::Error: stack level too deep #33

Closed
abrisse opened this issue Apr 17, 2013 · 5 comments
Closed

ActionView::Template::Error: stack level too deep #33

abrisse opened this issue Apr 17, 2013 · 5 comments

Comments

@abrisse
Copy link
Contributor

abrisse commented Apr 17, 2013

When migrating from rabl to rabl-rails I encounter a problem. Let's say you have 2 views in which you can extends each other under 2 different conditions that cannot be true at the same time.

Postulate : condition_A = !condition_B

# x/show.rabl
object :@x
attributes :id

condition(->(_) { condition_A } do
  extends 'y/show'
end
# y/show.rabl
object :@y
attributes :id

condition(->(_) { condition_B } do
  extends 'x/show'
end

That case triggers a ActionView::Template::Error: stack level too deep error when rendered. I guess that because the views are compiled contrary to the rabl gems.

@ccocchi
Copy link
Owner

ccocchi commented Apr 22, 2013

Hmm no, this should word because extends will only be called if the condition is true. I think the problem is that both your condition are true in your case.

@abrisse
Copy link
Contributor Author

abrisse commented May 24, 2013

@ccocchi : this is definitely a bug. Try to define in a rabl template 'items/show.rabl' :

object @resource

condition(->(item) { false }) do
  extends 'items/show'
end

It will raise :

ActionView::Template::Error (stack level too deep):
  rabl-rails (0.3.1) lib/rabl-rails/compiler.rb:17

Looks like the block is executed even if the condition is false. In fact the block won't be displayed if the condition is false but will nevertheless be executed.

@ccocchi
Copy link
Owner

ccocchi commented May 28, 2013

You're right, condition body are evaluated at compilation time so it will raise, but it is not a bug. You're trying to introduce a circular reference which is never a good idea, and is often due to a bad design so it won't be added to rabl-rails.

You can resolve your issue by extracting into a partial everything you will need in your x template from y template, and include it once in your y template and once in your x template inside your condition body. This way you will never a case of circular reference, which is a lot safer in my opinion.

@ccocchi ccocchi closed this as completed May 28, 2013
@brunoald
Copy link

brunoald commented Oct 1, 2014

I can't see a problem on using circular references when you have a clear "breakpoint". As far as I know, most recursive algorithms work based on this premise. You should only be careful ensuring there's always a "breakpoint". In my opinion, recursive structures are not necessarily bad design. It might be the case that they're a requirement. I'm trying to create a recursive JSON structure of comments within comments, but I'm getting the same problem that abrisse got.

@ccocchi
Copy link
Owner

ccocchi commented Oct 1, 2014

You're right, it makes sense when you're doing recursive templates, but that's different from what @abrisse was trying to achieve.

At the moment you won't be able to use extends with recursivity because of how rabl-rails works. Since templates are "compiled" into plain ruby objects without any context, the break condition will never be evaluated, hence the stack error.

But we could imagine a new directive extends_recursive "some_template", ->(obj) { break condition }) that would delegate extends replacement at rendering time unless the break condition is met.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants