ccocchi / rabl-rails

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

Support of block in RablRails::Compiler#child #32

Closed abrisse closed 11 years ago

abrisse commented 11 years ago

RablRails::Compiler#child doesn't seem to support blocks.

With the gem rabl, I currently have the following view:

object :@set

attributes :id, :name, :items

child(:items => :items) do |items|
    extends get_configuration_item_view(items)
end

get_configuration_item_view is a helper that returns the view able to render the items depending of the class of these items (dynamic because of polymorphism).

How to achieve that using rabl-rails ?

ccocchi commented 11 years ago
node(:items) do
  partial(get_configuration_item_view(@set.items), object: @set.items)
end

should do the trick. When dealing with dynamic, you can always be sure that you need to use node or merge

abrisse commented 11 years ago

OK @set = nil in the block so it worked using:

node(:items) do |set|
  partial(V1::ResourcesHelper.get_configuration_item_view(set.items), object: set.items)
end

Btw what is your advice concerning the helpers with rabl-rails ? Declaring them in RablRails::Compiler is very practical because they can be called directly but I don't like monkey patching :

object :@annotation

attributes :id, :media_id, :subject_id

if_included?(:media) do
  child(:media) do
    extends 'v1/medias/show'
  end
end

and in config/initializers:

module RablRails

  # Class that will compile RABL source code into a hash
  # representing data structure
  #
  class Compiler
    def if_included?(element)
      condition(->(annotation) { Module.check?(element) }) do
        yield
      end
    end
  end
end

How to do it properly ?

ccocchi commented 11 years ago

Sadly, there is no way to include a custom helper in rabl-rails currently.

The best way to achieve what you're trying to do would be to use partial:

# include_media.json.rabl
condition(->(annotation) { Module.check?(element) }) do
  child(:media) do
    extends 'v1/medias/show'
  end
end

# show.json.rabl
extends('include_media')
abrisse commented 11 years ago

Thanks Christopher for the feedback. Last question before closing this thread (you should add your answers to the Wiki)

How to access from my view the variables set in my controller like @set. For example:

# in app/controllers/item.rb
def show
   @item = Item.find(...)
   @user = User.find(...)
   respond_with @item
end

# in app/views/item/show.rabl
node(:owned) do |item|
  @user == item.owner ? true : false
end

does not work.

ccocchi commented 11 years ago

Yes that's the correct way to to it. But it seems you're using a gem that is messing with ActionController#assigns: first the issue with RSpec and now that.

Are you using a gem that deals with rendering or your controller (such as decent_exposure or focused_controller) ?

abrisse commented 11 years ago

Tried on a different project and it worked. I closed this issue and will investigate the problem. Thanks!