Giter Site home page Giter Site logo

grape-roar's Introduction

Grape::Roar

Gem Version Build Status Dependency Status Code Climate

Use Roar with Grape.

Demo

The grape-with-roar project deployed here on heroku.

Installation

Add the grape, roar and grape-roar gems to Gemfile.

gem 'grape'
gem 'roar'
gem 'grape-roar'

If you're upgrading from an older version of this gem, please see UPGRADING.

Usage

Tell your API to use Grape::Formatter::Roar

class API < Grape::API
  format :json
  formatter :json, Grape::Formatter::Roar
end

Use Grape's Present

Include Grape::Roar::Representer into a representer module after any Roar mixins, then use Grape's present keyword.

module ProductRepresenter
  include Roar::JSON
  include Roar::Hypermedia
  include Grape::Roar::Representer

  property :title
  property :id
end
get 'product/:id' do
  present Product.find(params[:id]), with: ProductRepresenter
end

Presenting collections works the same way. The following example returns an embedded set of products in the HAL Hypermedia format.

module ProductsRepresenter
  include Roar::JSON::HAL
  include Roar::Hypermedia
  include Grape::Roar::Representer

  collection :entries, extend: ProductRepresenter, as: :products, embedded: true
end
get 'products' do
  present Product.all, with: ProductsRepresenter
end

Accessing the Request Inside a Representer

The formatter invokes to_json on presented objects and provides access to the requesting environment via the env option. The following example renders a full request URL in a representer.

module ProductRepresenter
  include Roar::JSON
  include Roar::Hypermedia
  include Grape::Roar::Representer

  link :self do |opts|
    request = Grape::Request.new(opts[:env])
    "#{request.url}"
  end
end

Decorators

If you prefer to use a decorator class instead of modules.

class ProductRepresenter < Grape::Roar::Decorator
  include Roar::JSON
  include Roar::Hypermedia

  link :self do |opts|
    "#{request(opts).url}/#{represented.id}"
  end

  private

  def request(opts)
    Grape::Request.new(opts[:env])
  end
end
get 'products' do
  present Product.all, with: ProductsRepresenter
end

Relation Extensions

If you use either ActiveRecord or Mongoid, you can use the Grape::Roar::Extensions::Relations DSL to expose the relationships in between your models as a HAL response. The DSL methods used are the same regardless of what your ORM/ODM is, as long as there exists an adapter for it.

Designing Representers

Arguments passed to #relation are forwarded to roar. Single member relations (e.g. belongs_to) are represented using #property, collections are represented using #collection; arguments provided to #relation will be passed through these methods (i.e. additional arguments roar and representable accept).

A default base URI is constructed from a Grape::Request by concatenating the #base_url and #script_name properties. The resource path is extracted from the name of the relation.

Otherwise, the extensions attempt to look up the correct representer module/class for the objects (e.g. we infer the extend argument). You can always specify the correct representer to use on your own.

Example Models
class Item < ActiveRecord::Base
  belongs_to :cart
end

class Cart < ActiveRecord::Base
  has_many :items  
end
Example Representers
class ItemEntity < Grape::Roar::Decorator
  include Roar::JSON
  include Roar::JSON::HAL
  include Roar::Hypermedia

  include Grape::Roar::Extensions::Relations

  # Cart will be presented under the _embedded key
  relation :belongs_to, :cart, embedded: true

  link_self
end

class CartEntity < Grape::Roar::Decorator
  include Roar::JSON
  include Roar::JSON::HAL
  include Roar::Hypermedia

  include Grape::Roar::Extensions::Relations

  # Items will be presented under the _links key
  relation :has_many, :items, embedded: false

  link_self
end

Although this example uses Grape::Roar::Decorator, you can also use a module as show in prior examples above. If doing so, you no longer have to mix in Grape::Roar::Representer.

Example Item
{
    "_embedded": {
        "cart": {
            "_links": {
                "self": {
                    "href": "http://example.org/carts/1"
                },
                "items": [{
                    "href": "http://example.org/items/1"
                }]
            }
        }
    },
    "_links": {
        "self": {
            "href": "http://example.org/items/1"
        }
    }
}
Example Cart
{
    "_links": {
        "self": {
            "href": "http://example.org/carts/1"
        },
        "items": [{
            "href": "http://example.org/items/1"
        }, {
            "href": "http://example.org/items/2"
        }, {
            "href": "http://example.org/items/3"
        }, {
            "href": "http://example.org/items/4"
        }, {
            "href": "http://example.org/items/5"
        }]
    }
}

Errors

Should you incorrectly describe a relationship (e.g. you specify has_one but your model specifies has_many), an exception will be raised to notify you of the mismatch:

Grape::Roar::Extensions::Relations::Exceptions::InvalidRelationError:
  Expected Mongoid::Relations::Referenced::One, got Mongoid::Relations::Referenced::Many!

Change how URLs are presented

The opts hash below is the same one as shown in prior examples.

Override base URI mappings
class BarEntity < Grape::Roar::Decorator
  include Roar::JSON
  include Roar::JSON::HAL
  include Roar::Hypermedia

  include Grape::Roar::Extensions::Relations

  # This is our default implementation
  map_base_url do |opts|
    request = Grape::Request.new(opts[:env])
    "#{request.base_url}#{request.script_name}"
  end

  relation :has_many, :bars, embedded: false
end
Override resource URI mappings
class BarEntity < Grape::Roar::Decorator
  include Roar::JSON
  include Roar::JSON::HAL
  include Roar::Hypermedia

  include Grape::Roar::Extensions::Relations

  # This is our default implementation
  map_resource_path do |_opts, object, relation_name|
    "#{relation_name}/#{object.id}"
  end

  relation :has_many, :bars, embedded: false
end

Designing Adapters

If you have custom domain objects, you can create an adapter to make your models compatible with the DSL methods. Below is an example of the ActiveRecord adapter.

Example: ActiveRecord Adapter
module Extensions
  module RelationalModels
    module Adapter
      class ActiveRecord < Base
        include Validations::ActiveRecord

        # We map your domain object to the correct adapter
        # during runtime.
        valid_for { |klass| klass < ::ActiveRecord::Base }

        def collection_methods
          @collection_methods ||= %i(has_many has_and_belongs_to_many)
        end

        def name_for_represented(represented)
          klass_name = case represented
                       when ::ActiveRecord::Relation
                         represented.klass.name
                       else
                         represented.class.name
                       end
          klass_name.demodulize.pluralize.downcase
        end

        def single_entity_methods
          @single_entity_methods ||= %i(has_one belongs_to)
        end
      end
    end
  end
end
Validations

Errors are handled by creating methods corresponding to those in collection_methods and single_entity_methods. For example, this is the validator for belongs_to:

module ActiveRecord
  include Validations::Misc

  def belongs_to_valid?(relation)
    relation = klass.reflections[relation]

    return true if relation.is_a?(
      ::ActiveRecord::Reflection::BelongsToReflection
    )

    # Provided by Validations::Misc
    invalid_relation(
      ::ActiveRecord::Reflection::BelongsToReflection,
      relation.class
    )
  end
end

After writing your validation methods, just mix them into your adapter. You can choose to not write validation methods; they are only invoked if your adapter responds to them.

Contributing

See CONTRIBUTING.

Copyright and License

MIT License, see LICENSE for details.

(c) 2012-2014 Daniel Doubrovkine & Contributors, Artsy

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

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

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

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'",

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!

::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

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?

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?

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

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?

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

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

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)>'

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.