GithubHelp home page GithubHelp logo

grape-roar's People

Contributors

alan-andrade avatar dahie avatar dblock avatar mach-kernel avatar reiz avatar yuki24 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grape-roar's Issues

Nested representers

I'm having nested representers as following:
notifications_representers
** notification_representers
**** comment_representers
****** post_representers
******** image_representers

When I render a list of notifications with a type of comment and post title and post's image. But I see there are a few records that have image's attributes override to whole post attributes. Please tell me any wrong?

::nested hypermedia ::link raises an error

Hello,

A question on how to use nested attributes in either decorators/representers. In either way I get an error undefined methodlink' for #Class:0x007f8b441382c0`

module TupApi
  module Presenters
    class ItemPresenterV2D20141223 < Grape::Roar::Decorator
      include Roar::Representer::JSON
      include Roar::Representer::Feature::Hypermedia
      include Grape::Roar::Representer

      nested :images do
        link 'images:large_url' do
          "link"
        end
      end
    end
  end
end
        get ":id" do
          TupApi::Presenters::ItemPresenterV2D20141223.new(Item.find(params[:id]))
        end

I'm using version 0.2.0 with Grape 0.9.0.

Thanks

Next version of Roar defines Representer

See https://github.com/apotonick/roar/blob/master/lib/roar/representer.rb, will conflict with something like this:

message: "class or module required",
backtrace: [
"/Users/dblock/.rvm/gems/ruby-2.0.0-p353/gems/representable-2.0.0.rc2/lib/representable/represent.rb:4:in `is_a?'",
"/Users/dblock/.rvm/gems/ruby-2.0.0-p353/gems/representable-2.0.0.rc2/lib/representable/represent.rb:4:in `represent'",
"/Users/dblock/.rvm/gems/ruby-2.0.0-p353/bundler/gems/grape-4efcc0b88545/lib/grape/endpoint.rb:358:in `present'",
"/Users/dblock/source/gravity/dblock/app/api/v2/status_endpoint.rb:10:in `block (2 levels) in <class:StatusEndpoint>'",
"/Users/dblock/.rvm/gems/ruby-2.0.0-p353/bundler/gems/grape-4efcc0b88545/lib/grape/endpoint.rb:43:in `call'",
"/Users/dblock/.rvm/gems/ruby-2.0.0-p353/bundler/gems/grape-4efcc0b88545/lib/grape/endpoint.rb:43:in `block in generate_api_method'",

Add a CRUD extension

See https://github.com/dblock/grape-with-roar/blob/765b6fc0c117e70546161ced37da86cc0e18a8d4/api/extensions/crud_extension.rb, a simple CRUD extension that lets you write API crud in a much more elegant way.

create

spline = create Acme::Models::Spline, with: Acme::Api::Presenters::SplinePresenter, from: params[:spline]
present spline, with: Acme::Api::Presenters::SplinePresenter

update

spline = Acme::Models::Spline.find(params[:uuid])
update spline, with: Acme::Api::Presenters::SplinePresenter, from: params[:spline]

delete

spline = Acme::Models::Spline.find(params[:uuid])
delete spline, with: Acme::Api::Presenters::SplinePresenter

Accessing options inside link method

After bumping Roar from 1.0.1 to 1.0.4, having issues with accessing options in link method block.

representable gem was also bumped from 2.1.8 to 3.0.0 by virtue of me upgrading reform from 1.2.6 to 2.1.0.

No longer works:

class ClientsPresenter
  link :self do |options|
    options => nil ???
  end
end

With this calling present method:

resource :clients do
  get do
    present clients, with: ClientsPresenter
  end
end

I certainly do not have complete understanding of interplay between Roar ~ Representable ~ Grape libraries, but any thoughts/discussion would be really appreciated!

Thanks!

Add support for documentation fields

Grape exposures give you entity_name, exposures and documentation. We can add those for out-of-the-box support for https://github.com/tim-vandecasteele/grape-swagger.

module Grape
  module Roar
    module Representer
      def self.included(base)
        base.extend(ClassMethods)
      end

      module ClassMethods
        def entity_name
          self.name.split('::').last.gsub(/Presenter$/, '')
        end

        def exposures
          {}
        end

        def documentation
          Hash[representable_attrs.map do |attribute|
            property_name = attribute[:as].evaluate nil, nil
            next if property_name == '_links'
            [ property_name, { desc: attribute[:desc], type: attribute[:type] }]
          end.compact]
        end
      end
    end
  end
end

Dynamic options to to_json

I often find myself writing code like:

  ::FullActivityRepresenter.prepare(full_activity).to_json(student: current_student)

or..

  AttemptRepresenter.prepare(attempt).to_json(wrap: :attempt)

This gem looks great, but I can't seem to figure out an easy way to send data to the to_json method.

I would imagine some changes would need to happen here and here

Any ideas - if this is already possible - to how I can get this working?

Represented objects via `extend` are not serializable

If you put present instance, with: Presenter inside a cache block, it cannot be serialized. That is because its implementation looks like this:

def represent(object, options = {})
    object.extend self
    object
end

The objects gets serialized, but not its class definition with includes the extended methods.

A solution is to roll out a presenter that looks like this:

module Grape
  module Roar
    module Representer
      def self.included(base)
        base.extend(ClassMethods)
      end

      module ClassMethods
        def represent(object, options = {})
          object.extend self
          object.as_json(options) # usually cannot be `to_json` because Grape formatter would re-encode this
        end
      end
    end
  end
end

Maybe this should just be a class called Grape::Roar::Representer::JSON?

Lookup Representers Dynamically

Would you consider adding support for automatically extending object with the appropriate representer and releasing this as a gem?

Say something along these lines of:

def call(object, env)
  representer_name = "#{object.class}Representer"

  if Object.const_definied?(representer_name)
    representer_class = Object.const_get()
    object.extend(representer_class)
  end

  Grape::Formatter::Json.call object, env
end

Unable to represent properties from hash since grape v0.12.0

Hi there,

In advance: Please let me know if this is the wrong place to report this issue, it might be better to report at the representable gem or grape gem.

The issue: Since the update of the grape gem from v0.11.0 (still works) to v0.12.0 (doesn't work) I am unable to represent values from a hash using Grape-Roar, eg:

Gems:

  • roar (1.0.1)
  • grape (0.11.0)
  • grape-entity (0.4.5)
  • grape-roar (0.3.0)
module API
    module V1
        module Representers
            module SomeRepresenter 
                include Roar::JSON
                include Roar::Hypermedia
                include Grape::Roar::Representer

                property :some_property
            end
        end
    end
end

Throws:

> undefined method `some_property' for #<Hash:0x007f9f5b281318>

representable (2.2.3) lib/representable/binding.rb, line 98
-----------------------------------------------------------

ruby
   93         evaluate_option(:parse_filter, value, doc) { value }
   94       end
   95   
   96       def get
   97         evaluate_option(:getter) do
>  98           exec_context.send(getter)
   99         end
  100       end
  101   
  102       def set(value)
  103         evaluate_option(:setter, value) do


App backtrace
-------------

Full backtrace
--------------

 - representable (2.2.3) lib/representable/binding.rb:98:in `block in get'
 - representable (2.2.3) lib/representable/binding.rb:120:in `evaluate_option'
 - representable (2.2.3) lib/representable/binding.rb:97:in `get'
 - representable (2.2.3) lib/representable/binding.rb:56:in `block in compile_fragment'
 - representable (2.2.3) lib/representable/binding.rb:120:in `evaluate_option'
 - representable (2.2.3) lib/representable/binding.rb:55:in `compile_fragment'
 - representable (2.2.3) lib/representable/mapper.rb:73:in `compile_fragment'
 - representable (2.2.3) lib/representable/mapper.rb:33:in `serialize_property'
 - representable (2.2.3) lib/representable/mapper.rb:25:in `block in serialize'
 - representable (2.2.3) lib/representable/mapper.rb:24:in `serialize'
 - representable (2.2.3) lib/representable.rb:48:in `create_representation_with'
 - representable (2.2.3) lib/representable/hash.rb:35:in `to_hash'
 - representable (2.2.3) lib/representable/json.rb:35:in `to_json'
 - grape-roar (0.3.0) lib/grape/roar/formatter.rb:6:in `call'
 - grape (0.12.0) lib/grape/middleware/formatter.rb:34:in `block in after'
 - grape (0.12.0) lib/grape/middleware/formatter.rb:33:in `after'
 - grape (0.12.0) lib/grape/middleware/base.rb:25:in `call!'
 - grape (0.12.0) lib/grape/middleware/base.rb:18:in `call'
 - grape (0.12.0) lib/grape/middleware/base.rb:24:in `call!'
 - grape (0.12.0) lib/grape/middleware/base.rb:18:in `call'
 - grape (0.12.0) lib/grape/middleware/error.rb:27:in `block in call!'
 - grape (0.12.0) lib/grape/middleware/error.rb:26:in `call!'
 - grape (0.12.0) lib/grape/middleware/base.rb:18:in `call'
 - rack (1.6.4) lib/rack/head.rb:13:in `call'
 - rack (1.6.4) lib/rack/builder.rb:153:in `call'
 - grape (0.12.0) lib/grape/endpoint.rb:196:in `call!'
 - grape (0.12.0) lib/grape/endpoint.rb:184:in `call'
 - rack-mount (0.8.3) lib/rack/mount/route_set.rb:152:in `block in call'
 - rack-mount (0.8.3) lib/rack/mount/code_generation.rb:96:in `block in recognize'
 - rack-mount (0.8.3) lib/rack/mount/code_generation.rb:68:in `optimized_each'
 - rack-mount (0.8.3) lib/rack/mount/code_generation.rb:95:in `recognize'
 - rack-mount (0.8.3) lib/rack/mount/route_set.rb:141:in `call'
 - grape (0.12.0) lib/grape/api.rb:98:in `call'
 - grape (0.12.0) lib/grape/api.rb:33:in `call!'
 - grape (0.12.0) lib/grape/api.rb:29:in `call'
 - actionpack (4.2.0) lib/action_dispatch/routing/mapper.rb:51:in `serve'
 - actionpack (4.2.0) lib/action_dispatch/journey/router.rb:43:in `block in serve'
 - actionpack (4.2.0) lib/action_dispatch/journey/router.rb:30:in `serve'
 - actionpack (4.2.0) lib/action_dispatch/routing/route_set.rb:802:in `call'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:186:in `call!'
 - omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
 - warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
 - warden (1.2.3) lib/warden/manager.rb:34:in `call'
 - rack-cors (0.4.0) lib/rack/cors.rb:80:in `call'
 - rack (1.6.4) lib/rack/etag.rb:24:in `call'
 - rack (1.6.4) lib/rack/conditionalget.rb:25:in `call'
 - rack (1.6.4) lib/rack/head.rb:13:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/flash.rb:260:in `call'
 - rack (1.6.4) lib/rack/session/abstract/id.rb:225:in `context'
 - rack (1.6.4) lib/rack/session/abstract/id.rb:220:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/cookies.rb:560:in `call'
 - activerecord (4.2.0) lib/active_record/query_cache.rb:36:in `call'
 - activerecord (4.2.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:647:in `call'
 - activerecord (4.2.0) lib/active_record/migration.rb:378:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
 - activesupport (4.2.0) lib/active_support/callbacks.rb:88:in `_run_callbacks'
 - activesupport (4.2.0) lib/active_support/callbacks.rb:734:in `_run_call_callbacks'
 - activesupport (4.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
 - actionpack (4.2.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/reloader.rb:73:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
 - better_errors (2.1.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
 - better_errors (2.1.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
 - better_errors (2.1.1) lib/better_errors/middleware.rb:57:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
 - web-console (2.1.3) lib/web_console/middleware.rb:37:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
 - railties (4.2.0) lib/rails/rack/logger.rb:38:in `call_app'
 - railties (4.2.0) lib/rails/rack/logger.rb:20:in `block in call'
 - activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `block in tagged'
 - activesupport (4.2.0) lib/active_support/tagged_logging.rb:26:in `tagged'
 - activesupport (4.2.0) lib/active_support/tagged_logging.rb:68:in `tagged'
 - railties (4.2.0) lib/rails/rack/logger.rb:20:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
 - rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
 - rack (1.6.4) lib/rack/runtime.rb:18:in `call'
 - activesupport (4.2.0) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
 - rack (1.6.4) lib/rack/lock.rb:17:in `call'
 - actionpack (4.2.0) lib/action_dispatch/middleware/static.rb:113:in `call'
 - rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
 - utf8-cleaner (0.0.9) lib/utf8-cleaner/middleware.rb:18:in `call'
 - railties (4.2.0) lib/rails/engine.rb:518:in `call'
 - railties (4.2.0) lib/rails/application.rb:164:in `call'
 - thin (1.6.3) lib/thin/connection.rb:86:in `block in pre_process'
 - thin (1.6.3) lib/thin/connection.rb:84:in `pre_process'
 - thin (1.6.3) lib/thin/connection.rb:53:in `process'
 - thin (1.6.3) lib/thin/connection.rb:39:in `receive_data'
 - eventmachine (1.0.7) lib/eventmachine.rb:187:in `run'
 - thin (1.6.3) lib/thin/backends/base.rb:73:in `start'
 - thin (1.6.3) lib/thin/server.rb:162:in `start'
 - thin (1.6.3) lib/thin/controllers/controller.rb:87:in `start'
 - thin (1.6.3) lib/thin/runner.rb:200:in `run_command'
 - thin (1.6.3) lib/thin/runner.rb:156:in `run!'
 - thin (1.6.3) bin/thin:6:in `<top (required)>'

undefined method `entries'

Guys, I have some trouble with this gem.
I have such error caught error of type NoMethodError in after callback inside Grape::Middleware::Formatter : undefined method `entries' for #<Message
When i present conversations.
This is my code.

api/v1/conversations
api/v1/conversations/id/messages

conversations.rb
present conversations, with: App::API::ConversationsCollection

messages.rb
present messages, with: App::API::MessagesCollection

presenters/conversations/collection.rb

class App::API::ConversationsCollection < App::API::Collection
  collection :entries, extend: App::API::ConversationsSingle, as: :conversations
end

presenters/conversations/single.rb

class App::API::ConversationsSingle < App::API::Single
  properties :id
  property :user, exec_context: :decorator

  def user
    App::API::Users.new(represented.user).to_hash
  end
end

presenters/messages/collection

class App::API::MessagesCollection < App::API::Collection
  collection :entries, extend: App::API::MessagesSingle, as: :messages
end

presenters/messages/single

class App::API::MessagesSingle < App::API::Single
  properties :id
  property :user, exec_context: :decorator

  def user
    App::API::Users.new(represented.user).to_hash
  end
end

collection.rb

require 'roar/decorator'
require 'roar/json'

class App::API::Collection < Grape::Roar::Decorator
  include Roar::JSON
end

single.rb

require 'roar/decorator'
require 'roar/json'

class App::API::Single < Grape::Roar::Decorator
  include Roar::JSON

  class << self
    def properties(*props)
      props.each { |prop| property prop }
    end
  end
end

decorator.rb

require 'roar/decorator'
require 'roar/json'

class App::API::Decorator < Grape::Roar::Decorator
  include Roar::JSON
  include Roar::Hypermedia
  include Grape::Roar::Representer
end

Telling a representer to represent nil adds all of that class's methods to nil

The code causing this behavior is https://github.com/ruby-grape/grape-roar/blob/master/lib/grape/roar/representer.rb#L10

Example

user = User.find_by(email: '[email protected]')
# user => nil
present user, with: User::Representer
# User::Representer.ancestors => [..., Grape::Roar::Representer, ...]

Obviously there's a bug in this application code, but the result is that, since nil is a singleton, now every time the application asks for nil, it gets it, but with all kinds of fun stuff mixed in, like a custom #to_hash that, for instance, mucks with the instantiation of ActionController::Parameters and causes completely unrelated pages in an app to blow up

Thoughts? I'd be happy to submit a PR, but i only have a cursory understanding of all the interplay between grape, roar, grape-roar, representable, etc. and just tossing in a nil check might not be the best approach

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.