Giter VIP home page Giter VIP logo

her's Issues

Authenticating to Rails API using authenticate_or_request_with_http_token

The sample code in the readme

def call(env)
  env[:request_headers]["X-API-Token"] = @options[:token] if @options.include?(:token)
  @app.call(env)
end

produces the following header: "X-API-TOKEN"=>"bb2b2dd75413d3"

Using the built-in Rails token authentication method (authenticate_or_request_with_http_token) it needs to come in like this: "HTTP_AUTHORIZATION"=>"Token token=\"bb2b2dd75413d3\"".

Am I missing anything or how can I change the sent header?

Ability to access HTTP headers via Model

Thank you for the great library.

I believe this is a feature request unless there is a clean way to pass the needed information to a faraday middleware layer that I'm not seeing.

I'm hoping for the ability to set/read request/response headers from the model. The specific use case is to embed pagination information in the request headers rather than sending it via query params and more importantly, avoid having to chunk up the response JSON to embed metadata needed for pagination such as the total number of items.

I've taken a look over the code and at first glance it seems a lot of changes would need to be made to pass header information up/down the stack. I'm happy to take a crack at it if some guidance could be offered in terms of preferred style.

Create an example application using Her

I’m going to create an example application (probably using the Twitter API) to show how easy it is to create REST API-backed Web applications with Her.

undefined method `delete' for nil:NilClass

Hey All,

Running into an issue getting started with her. It's probably me, but wanted to run it by you.

I've got a simple model using Her:

class Course < ActiveRecord::Base
  include Her::Model
end

Here's my initilizer:

Her::API.setup :url => "http://localhost:3010" do |connection|
  connection.use Faraday::Request::UrlEncoded
  connection.use Her::Middleware::FirstLevelParseJSON
  connection.use Faraday::Adapter::NetHttp
end

I'm trying to do a basic find (/courses/1) in my client. The find is calling my api, which is correctly returning {"id":1,"name":"Alondra"}.

However, it looks like parsing that response is causing problems. Here's the full error I'm getting:

activerecord (3.2.8) lib/active_record/attribute_methods/write.rb:28:in write_attribute' activerecord (3.2.8) lib/active_record/attribute_methods/dirty.rb:67:inwrite_attribute'
activerecord (3.2.8) lib/active_record/attribute_methods/write.rb:14:in id=' her (0.3.6) lib/her/model/orm.rb:36:inblock in use_setter_methods'
her (0.3.6) lib/her/model/orm.rb:33:in each' her (0.3.6) lib/her/model/orm.rb:33:ininject'
her (0.3.6) lib/her/model/orm.rb:33:in use_setter_methods' her (0.3.6) lib/her/model/orm.rb:16:ininitialize'
her (0.3.6) lib/her/model/orm.rb:196:in new' her (0.3.6) lib/her/model/orm.rb:196:inblock (2 levels) in find'
her (0.3.6) lib/her/model/http.rb:22:in request' her (0.3.6) lib/her/model/orm.rb:195:inblock in find'
her (0.3.6) lib/her/model/orm.rb:194:in map' her (0.3.6) lib/her/model/orm.rb:194:infind'
app/controllers/course_s_controller.rb:7:in show' actionpack (3.2.8) lib/action_controller/metal/implicit_render.rb:4:insend_action'
actionpack (3.2.8) lib/abstract_controller/base.rb:167:in process_action' actionpack (3.2.8) lib/action_controller/metal/rendering.rb:10:inprocess_action'
actionpack (3.2.8) lib/abstract_controller/callbacks.rb:18:in block in process_action' activesupport (3.2.8) lib/active_support/callbacks.rb:425:in_run__2721729234568045003__process_action__79657235857638791__callbacks'
activesupport (3.2.8) lib/active_support/callbacks.rb:405:in __run_callback' activesupport (3.2.8) lib/active_support/callbacks.rb:385:in_run_process_action_callbacks'
activesupport (3.2.8) lib/active_support/callbacks.rb:81:in run_callbacks' actionpack (3.2.8) lib/abstract_controller/callbacks.rb:17:inprocess_action'
actionpack (3.2.8) lib/action_controller/metal/rescue.rb:29:in process_action' actionpack (3.2.8) lib/action_controller/metal/instrumentation.rb:30:inblock in process_action'
activesupport (3.2.8) lib/active_support/notifications.rb:123:in block in instrument' activesupport (3.2.8) lib/active_support/notifications/instrumenter.rb:20:ininstrument'
activesupport (3.2.8) lib/active_support/notifications.rb:123:in instrument' actionpack (3.2.8) lib/action_controller/metal/instrumentation.rb:29:inprocess_action'
actionpack (3.2.8) lib/action_controller/metal/params_wrapper.rb:207:in process_action' activerecord (3.2.8) lib/active_record/railties/controller_runtime.rb:18:inprocess_action'
actionpack (3.2.8) lib/abstract_controller/base.rb:121:in process' actionpack (3.2.8) lib/abstract_controller/rendering.rb:45:inprocess'
actionpack (3.2.8) lib/action_controller/metal.rb:203:in dispatch' actionpack (3.2.8) lib/action_controller/metal/rack_delegation.rb:14:indispatch'
actionpack (3.2.8) lib/action_controller/metal.rb:246:in block in action' actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:incall'
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:in dispatch' actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:36:incall'
journey (1.0.4) lib/journey/router.rb:68:in block in call' journey (1.0.4) lib/journey/router.rb:56:ineach'
journey (1.0.4) lib/journey/router.rb:56:in call' actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:600:incall'
omniauth (1.1.1) lib/omniauth/strategy.rb:177:in call!' omniauth (1.1.1) lib/omniauth/strategy.rb:157:incall'
warden (1.2.1) lib/warden/manager.rb:35:in block in call' warden (1.2.1) lib/warden/manager.rb:34:incatch'
warden (1.2.1) lib/warden/manager.rb:34:in call' actionpack (3.2.8) lib/action_dispatch/middleware/best_standards_support.rb:17:incall'
rack (1.4.1) lib/rack/etag.rb:23:in call' rack (1.4.1) lib/rack/conditionalget.rb:25:incall'
actionpack (3.2.8) lib/action_dispatch/middleware/head.rb:14:in call' actionpack (3.2.8) lib/action_dispatch/middleware/params_parser.rb:21:incall'
actionpack (3.2.8) lib/action_dispatch/middleware/flash.rb:242:in call' rack (1.4.1) lib/rack/session/abstract/id.rb:205:incontext'
rack (1.4.1) lib/rack/session/abstract/id.rb:200:in call' actionpack (3.2.8) lib/action_dispatch/middleware/cookies.rb:339:incall'
activerecord (3.2.8) lib/active_record/query_cache.rb:64:in call' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:incall'
actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:28:in block in call' activesupport (3.2.8) lib/active_support/callbacks.rb:405:in_run__2801846045624969339__call__293598484128179998__callbacks'
activesupport (3.2.8) lib/active_support/callbacks.rb:405:in __run_callback' activesupport (3.2.8) lib/active_support/callbacks.rb:385:in_run_call_callbacks'
activesupport (3.2.8) lib/active_support/callbacks.rb:81:in run_callbacks' actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:27:incall'
actionpack (3.2.8) lib/action_dispatch/middleware/reloader.rb:65:in call' actionpack (3.2.8) lib/action_dispatch/middleware/remote_ip.rb:31:incall'
actionpack (3.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:16:in call' actionpack (3.2.8) lib/action_dispatch/middleware/show_exceptions.rb:56:incall'
railties (3.2.8) lib/rails/rack/logger.rb:26:in call_app' railties (3.2.8) lib/rails/rack/logger.rb:16:incall'
disable_assets_logger (1.0.0) lib/disable_assets_logger/middleware.rb:11:in call' actionpack (3.2.8) lib/action_dispatch/middleware/request_id.rb:22:incall'
rack (1.4.1) lib/rack/methodoverride.rb:21:in call' rack (1.4.1) lib/rack/runtime.rb:17:incall'
activesupport (3.2.8) lib/active_support/cache/strategy/local_cache.rb:72:in call' rack (1.4.1) lib/rack/lock.rb:15:incall'
actionpack (3.2.8) lib/action_dispatch/middleware/static.rb:62:in call' railties (3.2.8) lib/rails/engine.rb:479:incall'
railties (3.2.8) lib/rails/application.rb:223:in call' rack (1.4.1) lib/rack/content_length.rb:14:incall'
railties (3.2.8) lib/rails/rack/log_tailer.rb:17:in call' thin (1.5.0) lib/thin/connection.rb:81:inblock in pre_process'
thin (1.5.0) lib/thin/connection.rb:79:in catch' thin (1.5.0) lib/thin/connection.rb:79:inpre_process'
thin (1.5.0) lib/thin/connection.rb:54:in process' thin (1.5.0) lib/thin/connection.rb:39:inreceive_data'
eventmachine (1.0.0) lib/eventmachine.rb:187:in run_machine' eventmachine (1.0.0) lib/eventmachine.rb:187:inrun'
thin (1.5.0) lib/thin/backends/base.rb:63:in start' thin (1.5.0) lib/thin/server.rb:159:instart'
rack (1.4.1) lib/rack/handler/thin.rb:13:in run' rack (1.4.1) lib/rack/server.rb:265:instart'
railties (3.2.8) lib/rails/commands/server.rb:70:in start' railties (3.2.8) lib/rails/commands.rb:55:inblock in <top (required)>'
railties (3.2.8) lib/rails/commands.rb:50:in tap' railties (3.2.8) lib/rails/commands.rb:50:in<top (required)>'
script/rails:6:in require' script/rails:6:in

'

Any thoughts?

thanks,
Charlie

Typhoeus/Parallel request Compatability

Background

Hey, awesome gem! I've been working on something of an ORM myself, and I wanted to implement parallel requesting with Typhoeus. I might still implement this myself, but I really enjoy this implementation and figured this would be a good spot to add such functionality.

The Question

So, does anyone have any interest in cooperating to add parallel requesting with Typhoeus on here?

Initial glance

At a glance, just using:

Her::API.setup :url => "http://example-url.example.com" do |connection|
  # ...
  connection.use Faraday::Adapter::Typhoeus
end

There's an error upon request:

Ethon::Errors::InvalidOption: The option: disable_ssl_peer_verification is invalid.
from ...@broker/gems/ethon-0.5.7/lib/ethon/easy.rb:254:in `block in set_attributes'

tl;dr

Hoping to get some parallel request implementation, potentially on Typhoeus, what are your thoughts?

Issue with plural-named has_one element

hi all, first off, we've been looking for support like this since our UI will be accessing only REST services and I found this very easy to integrate (even tweaking Faraday with our client certs and custom headers) and is mostly working with one of our services. But I noticed the following issue. we have a person service and the person has one details, ie
class Person
include Her::Model
has_one :details
has_one :summary....
and I created a Details class but my test errors with
undefined method `new' for nil:NilClass
But if I changed details.rb to detail.rb (and classname Details to Detail), and leave the above "has_one: details" as-is, then it works. I also tried the opposite, "has_one :detail" but it failed too since the JSON had "details"
I noticed a couple instances of using pluralize in the Her source but not sure if related to this issue. Now, arguably, the server-side guys maybe should have gone with one detail instead of details since its not has_many details, but from a human readable perspective I can see their design.
Any idea why this is happening? My workaround above is fine for now but just inconsistent.
thanks for your time.

Undefined Method '+' for nil:NilClass

Hopefully this is not a stupid question, or something obvious, but I can't get Her to work at all. I've tried to follow the readme to the letter but I must be missing something.

Tried with ruby-1.8.7-p370, ree-1.8.7-2012.02, ruby-1.9.3-p194, same result each time.
Using rails 3.2.3

I have a model User in app2 which I want to pull from into app1.

# app1/Gemfile
gem 'her'

# app1/config/initializers/her.rb
# http://local.portal is app2, and I can access it fine through my browser

Her::API.setup :url => "http://local.portal" do |connection|
  connection.use Faraday::Request::UrlEncoded
  connection.use Her::Middleware::DefaultParseJSON
  connection.use Faraday::Adapter::NetHttp
end

# app1/models/user.rb
class User
  include Her::Model
end

# rails c
Loading development environment (Rails 3.2.3)
1.8.7-p370 :001 > u = User.all
NoMethodError: undefined method `+' for nil:NilClass
    from /home/tom/.rvm/rubies/ruby-1.8.7-p370/lib/ruby/1.8/net/http.rb:1118:in `addr_port'
    from /home/tom/.rvm/rubies/ruby-1.8.7-p370/lib/ruby/1.8/net/http.rb:1078:in `begin_transport'
    from /home/tom/.rvm/rubies/ruby-1.8.7-p370/lib/ruby/1.8/net/http.rb:1048:in `request'
    from /home/tom/.rvm/rubies/ruby-1.8.7-p370/lib/ruby/1.8/net/http.rb:1037:in `request'
    from /home/tom/.rvm/rubies/ruby-1.8.7-p370/lib/ruby/1.8/net/http.rb:543:in `start'
    from /home/tom/.rvm/rubies/ruby-1.8.7-p370/lib/ruby/1.8/net/http.rb:1035:in `request'
    from /home/tom/.rvm/rubies/ruby-1.8.7-p370/lib/ruby/1.8/net/http.rb:772:in `get'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/faraday-0.7.6/lib/faraday/adapter/net_http.rb:59:in `call'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/faraday-0.7.6/lib/faraday/request/url_encoded.rb:14:in `call'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/faraday-0.7.6/lib/faraday/response.rb:8:in `call'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/faraday-0.7.6/lib/faraday/connection.rb:210:in `run_request'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/faraday-0.7.6/lib/faraday/connection.rb:93:in `get'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/her-0.2/lib/her/api.rb:67:in `send'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/her-0.2/lib/her/api.rb:67:in `request'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/her-0.2/lib/her/model/http.rb:37:in `request'
    from /home/tom/.rvm/gems/ruby-1.8.7-p370@io/gems/her-0.2/lib/her/model/orm.rb:64:in `all'
    from (irb):11.8.7-p370 :002 > 

I've been working at this for a couple hours now, getting nowhere. I must be missing something very simple, but for the life of me can't see it. If you have any suggestions (or if this is actually a bug and I also missed THAT in the tickets), I am all ears.

Thanks, and I am really looking forward to using Her!

New Gem-Version

As you merged some stuff yesterday, it would be cool to have a new Version on RubyGems so we don't have to use your master branch :)

failed to parse root in json

Hi all,
I'd like to user Her to consume Rails based API. My application returns a json like

{
   "videos": [{id: 0, url: "http"}, .... ]
}

When in send a get request to /videos.json

but model like

class Video
   include Her::Model
   parse_root_in_json true
end

fails with can't convert Symbol int Integer.

Posting new entities attached to existing ones?

I'd love to be able to run

Post.find(10).comments.build({ :comment => "lol fristpost"}) 
  • is this ActiveRecord style post interface something that's planned, not-implemented-but-welcome-to-write, or actively rejected?

How to call a custom member action on a resource

Say you have a group resource within your api-server like this:

resources :groups do
  put :approve, on: :member
end

How to call this action from the Her Api?

I would expect something like Group.find(15).put(:approve) but that itsn't working. Could someone indicate if is possible?

Her models should respond correctly to the Rails link helper

Right now trying to do link_to(foo_path(@foo)) or link_to(@foo) will result in the wrong thing or a routing error. It would be cool if Her responded to whatever methods link_to depends on to do its thing. It might be as simple as implementing to_param or something, but it seems like it should be easy enough. You might have to assume more than you want to about the model though (e.g. presence of an id attribute). Either way, something to consider.

Can Her support the concept of scoped API objects?

One of the challenges we face working with REST ORMs is that only a few have a built in concept of per user or per request authorization - authorization to the API tends to be global in scope. In our use cases, we authorize as the user to the remote API and so need to scope authorization on a per instance / request basis. One of the ways we've worked around this with ActiveResource is exposing the concept of an authorization object that is passed on object initialization:

Cartridge.new :name => 'foo', :as => current_user

and then making sure that the appropriate remote calls in ActiveResource introspect the model object for the presence of that "as" object in order to build HTTP headers for the response (either BASIC or API token, as necessary). The :as object in this case exposes either to_headers or :user, :password / :to_api_token depending on what makes sense. In ActiveResource this is a fair amount of pain.

As I was looking at Her I liked that most API requests passed through an API object that could be scoped, although in many cases the scope was at the class level. From a pure architectural level, are you opposed to the idea that a Her API object might have a local scope (on an instance) or a global scope (on a model object) and that the instance would delegate up the chain to locate that object before making a new request? One implication with that is that new() and find() methods would need to properly inject the correct API object to factory created methods, but that did not seem insurmountable. The goal would be to allow a model to parameterize the HTTP requests it makes to the remote endpoint - I was working from the assumption that the cleanest way to do that would be to allow a model object to add middleware to the parent API object (thus specializing the call).

I took a rough stab at a branch to demonstrate the concept - https://github.com/smarterclayton/her/compare/experimental_api_scoping, with a Gist demonstrating mixing in of the API (https://gist.github.com/3361943). Some of the changes in the gist would also need to be in Her but the idea would be that specialization of an api object would be possible through any Her descended model class or instance. In this case it's demonstrating a mixin that looks for :as on the instance and adds a custom faraday middleware to requests that come from that instance.

A usage example is:

api = Her::API.new
api.setup :base_uri => "http://localhost" do |builder|
  ...
  builder.use Faraday::Adapter::NetHttp
end

class Model
  include Her::Model
  include ConsoleModel::WithAuthorization
  authorizes :with => ConsoleModel::Middleware::Authorizes
  uses_api api
end

model = Model.new :as => User.new('bob', 'password'), .... # other attributes
model.save # the presence of :as triggers api specialization such that the middleware

# or alternatively, if you prefer specialization of the model class

model = Model.as(User.new('bob', 'password').new #other attributes
model.save

Authorization is one example where this sort of middleware approach might make sense - model level caching mixins is possibly another:

 model = Model.cached(:for => 5.min).find('by_id')

Would you be opposed to a pull request exploring the minimal changes necessary to support an inheritance chain for API objects (allowing an instance to delegate to the class, which could delegate to its parent class, etc) and the support for specializing those objects? Is model specialization via class/eigenclass/instance inheritance something you've previously considered for Her?

Model-specific headers

What

Set headers for a model to be a Hash, Proc or lambda.

Why

This is for the case when your using an OAuth-based API, like Facebook, where you need to use the specific user token for any request. Token is also an attribute on the object so it must be evaluated per-user on request.

Proposed Change Example

class User
  include Her::Model

  headers Proc.new do |obj|
    'Authorize' => "token #{obj.token}"
  end

What are your thoughts? I can try to take a pass at this unless there is a better way or somehow I missed the feature while surfing through the source code.

her whitelists faraday options

Hi,
I'd like to ask the reasoning behind whitelisting faraday options instead of allowing them to be passed through. I recently had the need to specify a global timeout longer than the faraday default and had to utilize a round-about method (below) to apply that.

Thanks!

Whitelist line:
(https://github.com/remiprev/her/blob/master/lib/her/api.rb#L56)

Workaround:

my_api = Her::API.new
my_api.setup :url => 'foobar.com' do...
options = my_api.connection.instance_variable_get("@options") || {}
my_api.connection.instance_variable_set("@options", options.merge({:timeout => 60}))

parse "include root in json"?

When building an API with rails/active model serializers the root name is picked from the name of the model. How can I, in a middleware automatically set data to json[:model_name] ? Alternatively, is there any other way to do it?

Restrict operations

What

Restrict a Her::Model to only supporting certain operations.

Why

In the case where you want to use all the features of the Her ORM, but you only have read-only access to a given object.

Proposed DSL

class Profile
   include Her::Model

   # Whitelist options
   supports :read, :create, :update, :delete

   # Blacklist actions
   restricts :update, :delete
end

I like the idea of whitelisting with an :all over blacklisting, thoughts?

:after_find hook?

Do you have any plans to add an :after_find hook? Would you entertain a pull request with such a feature? ;)

ActiveModel Object

Her is really awesome, but it would be even more if it could returning ActiveModel object no?
Maybe with Rails 4? Is it something intentional?

Thanks a lot for your gem!

Not sending the correct parameters on create/update

I just started using her (so I'm probably missing something) but when I use the example code from the readme:

User.create :full_name => 'Nate'

The response is received as:

Started POST "/users" for 127.0.0.1 at 2012-10-31 11:39:32 -0400
Processing by UsersController#create as */*
  Parameters: {"full_name"=>"Nate"}
   (0.0ms)  begin transaction
  SQL (1.0ms)  INSERT INTO "users" ("created_at", "full_name", "updated_at") VALUES (?, ?, ?)  [["created_at", Wed, 31 Oct 2012 15:39:32 UTC +00:00], ["full_name", nil], ["updated_at", Wed, 31 Oct 2012 15:39:32 UTC +00:00]]

The create works (technically) but the full_name is blank because the parameter came across without being scoped under user. Is this supposed to be this way or am I missing something?

ssl support

Would you consider to add ssl connection option at Farraday connection establishment in
#50 Her::Api setup

Even nice way would be, allowing to pass the same options to setup, as to Farraday.new

Examples don't jive with the actual middleware stack order

The documentation here (specifically the first example) implies that if I add my middleware with use that I can run my code during both the request and response cycles. However, this is not true. In the example, the "X-API-TOKEN" header wouldn't get set until after the request had been made, which of course makes no sense.

This is the order of middleware before MyAuthentication is added (the default order):

Her::Middleware::FirstLevelParseJSON
Faraday::Request::UrlEncoded
Faraday::Adapter::NetHttp

When you use builder.use, you are appending to the end of the stack, after NetHttp. However, NetHttp, when called, performs the actual request. So, MyAuthentication doesn't get called until after we get a response.

There's a few solutions here. The easiest would, of course, be just updating the docs to use builder.insert 0, ... However, it would be nice if we had a way to use middleware while ensuring that it comes before the middleware that makes the actual request (e.g. NetHttp).

I'm happy to implement this, but I wanted to see what your opinion was on how this would best be done.

Relation collection has "belongs_to"-Object not set

Hi

We have the following two models:

class Domain < PluginHelpers::HerModel
  include Her::Model
  uses_api ::PdnsPlugin.api

  has_many :records
end

class Record < PluginHelpers::HerModel
  include Her::Model
  uses_api ::PdnsPlugin.api

  belongs_to :domain

  def name_with_domain
    "name.#{domain.name}"
  end
end

Now if I do the following, there will be a request like Domain.find(1) does for every record, means a lot of overhead for informations which already have been fetched.

domain = Domain.find(1)
domain.records.each do |record|
  puts record.name_with_domain
end

I think the problem is, that record.domain has not been set even though I accessed the Record-object coming from the Domain object.
Do you have any idea how to easily add this already fetched Domain object to the Record object?

undefined method `delete' for true:TrueClass when executing destroy

This is what I get when I execute 'destroy' on a resource. The resource itself is deleted afterwards.

>> j = PostgresRecoverJob.find("6e3421a41aacd3354c9fb9e7f1d0c854")
=> #<PostgresRecoverJob(recover_jobs/6e3421a41aacd3354c9fb9e7f1d0c854) status="queued" time="2013-04-02 22:04:03 +0200" message="" pct_complete=0 server="sauspiel" target="localhost" backup_id="20130402T171257" completed_at="" id="6e3421a41aacd3354c9fb9e7f1d0c854">
>> j.destroy
NoMethodError: undefined method `delete' for true:TrueClass
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/middleware/first_level_parse_json.rb:11:in `parse'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/middleware/first_level_parse_json.rb:29:in `on_complete'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.6/lib/faraday/response.rb:9:in `block in call'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.6/lib/faraday/response.rb:63:in `on_complete'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.6/lib/faraday/response.rb:8:in `call'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.6/lib/faraday/request/url_encoded.rb:14:in `call'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.6/lib/faraday/connection.rb:247:in `run_request'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/faraday-0.8.6/lib/faraday/connection.rb:100:in `delete'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/api.rb:88:in `request'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/http.rb:24:in `request'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/orm.rb:177:in `block in destroy'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:403:in `_run__1606273922648791830__destroy__1484856305865657010__callbacks'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:405:in `__run_callback'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:385:in `_run_destroy_callbacks'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:81:in `run_callbacks'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/orm.rb:176:in `destroy'
    from (irb):2
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /Users/hamann/workspace/sauspiel/sauspiel-rails/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>

Access Rails session from Faraday middleware

The README file has the following comment:

Her::API.setup :url => "https://api.example.com" do |builder|
  # This token could be stored in the client session
  builder.use MyAuthentication, :token => "..."
  # ...
end

Can you give me an example of how you could access the current Rails session from that code block? I've put the code in a Rails initialiser file.

Thanks

Can't destroy through association.

class Configuration
  include Her::Model
  has_many :publish_sets
end

class PublishSet
  include Her::Model
  belongs_to :configuration
end

This association works as expected for get requests:

Configuration.find(1234).publish_sets
GET .../configurations/1234/publish_sets

but for delete requests:

Configuration.find(1234).publish_sets.first.destroy
DELETE .../publish_sets/5678

I need to make it so that delete requests use the full nested url
DELETE .../configurations/1234/publish_sets/5678

I tried setting
collection_path("/configurations/:configuration_id/publish_sets")
but the publish_set objects i get back from the api don't have the configuration_id param, only a configuration object.

Is there anyway to do this kind of delete through the association instead of a delete_raw (how i'm doing it now)

Her model should handle 404 / 500 statuses

When I use a Her::Model and my request get a 404 response it's not treated as it should.

class Article
  include Her::Model
end

Article.find('nothing')
#=> #<Article(articles) error="404 Not Found">

Maybe some sort of exception should be raised like ActiveRecord::RecordNotFound when an AR.find fails.

EDIT:

When an API returns no body on 404 error, the JSON parser raises a MultiJson::DecodeError exception.

NoMethodError: undefined method `bytesize' for {}:Hash on #destroy

When I call #destroy on a Her::Model I get this error (I have try with different middlewares configuration/order, still get it):

NoMethodError: undefined method `bytesize' for {}:Hash
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1932:in `send_request_with_body'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1919:in `exec'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1317:in `block in transport_request'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1316:in `catch'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1316:in `transport_request'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1293:in `request'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1286:in `block in request'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:745:in `start'
  from /Users/Thibaud/.rbenv/versions/1.9.3-p327/lib/ruby/1.9.1/net/http.rb:1284:in `request'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/faraday-0.8.4/lib/faraday/adapter/net_http.rb:74:in `perform_request'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/faraday-0.8.4/lib/faraday/adapter/net_http.rb:37:in `call'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/faraday-0.8.4/lib/faraday/response.rb:8:in `call'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/faraday-0.8.4/lib/faraday/connection.rb:226:in `run_request'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/faraday-0.8.4/lib/faraday/connection.rb:87:in `delete'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/her-0.3.8/lib/her/api.rb:71:in `request'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/her-0.3.8/lib/her/model/http.rb:24:in `request'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/her-0.3.8/lib/her/model/orm.rb:173:in `block in destroy'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/her-0.3.8/lib/her/model/hooks.rb:65:in `wrap_in_hooks'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/her-0.3.8/lib/her/model/orm.rb:172:in `destroy'
  from (irb):2
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/railties-3.2.11/lib/rails/commands/console.rb:47:in `start'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/railties-3.2.11/lib/rails/commands/console.rb:8:in `start'
  from /Users/Thibaud/Codes/rails_app/vendor/ruby/1.9.1/gems/railties-3.2.11/lib/rails/commands.rb:41:in `<top (required)>'
  from script/rails:6:in `require'

Allow data wrapping when calling create/update

A Her model should provide an option to allow data wrapping when sending it to an API.
I'd like to see something like this:

class User
  include Her::Model
  params_wrapping true
end

When calling save or create or any other saving method, it would send the following:

{ user: { name: "user1", ... } }

Alternatively, a user could override the default wrapping key by providing it this way:

class User
  include Her::Model
  params_wrapping :person
end

It would send

{ person: { name: "user1", ... } }

(see also issue #41)

Relationships do not work correctly

I'm a bit confused, maybe you can help me

if have two classes

class PostgresBackupServer
  include Her::Model
  collection_path "servers"
  has_many :targets, :class_name => "PostgresBackupTarget"
end

class PostgresBackupTarget
  include Her::Model
  collection_path "servers/:postgres_backup_server/targets"
  attributes :path
  belongs_to :server, :class_name => "PostgresBackupServer"
end

this works so far

>> PostgresBackupServer.all[0].targets[0]
=> #<PostgresBackupTarget(servers/#<PostgresBackupServer:0x007f8eefce51c8>/targets/localhost) id="localhost" postgres_backup_server=#<PostgresBackupServer(servers/sauspiel) id="sauspiel" targets=[#<PostgresBackupTarget(servers/#<PostgresBackupServer:0x007f8eefce51c8>/targets/localhost) id="localhost" postgres_backup_server=#<PostgresBackupServer(servers/sauspiel) id="sauspiel" targets=[...]>>, #<PostgresBackupTarget(servers/#<PostgresBackupServer:0x007f8eefce51c8>/targets/ssh_localhost) id="ssh_localhost" postgres_backup_server=#<PostgresBackupServer(servers/sauspiel) id="sauspiel" targets=[...]>>]>>

but this doesn't work

>> PostgresBackupTarget.all(:_postgres_backup_server => "sauspiel")
Her::Errors::PathError: Missing :_postgres_backup_server parameter to build the request path. Path is `servers/:postgres_backup_server/targets/:id`. Parameters are `{:id=>"localhost"}`.
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/paths.rb:70:in `block in build_request_path'
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/paths.rb:68:in `gsub'
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/paths.rb:68:in `build_request_path'
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/paths.rb:15:in `request_path'
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/her-0.5.2/lib/her/model/introspection.rb:15:in `inspect'
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /Users/hamann/workspace/tmp/railstest/vendor/bundle/ruby/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

What's the problem here?

Metadata usage?

I was trying to use metadata with my Her model. While the middlware segregates the response into data, errors and metadata, but on model initialization the parameters of metadata being send-in are parsed_data[:data] instead of parsed_data[:metadata].
Saw your comment
#16 (comment)

Was curious to know if it is something that has been done intentionally or is it some feature in-dev?

Introspecting a model with a custom path throws an exception

Given the following model:

class User
  collection_path "/companies/:company_id/users"
end

If in the console I do the following it works:

> User.all({company_id: 1}).first.id
1

However the following throws an error:

> User.all({company_id: 1}).first.id
Her::Errors::PathError: Missing :_company_id parameter to build the request path (/companies/:company_id/users).

This is because #inspect calls #request_path again, but without the parameters.

handle relationships with no data

Some of the data I get back from the server will have nil data. e.g.

class Token
  include Her::Model

  has_one :user
end
{ "id": "...", "user":null, ... }
% rails c          
Loading development environment (Rails 3.2.3)
1.9.3p194 :001 > t = Token.get("token", :site_key =>'site')
(Object doesn't support #inspect)
 =>  
1.9.3p194 :003 > t.inspect
NoMethodError: undefined method `include?' for nil:NilClass
    from [...]/gems/her-0.2/lib/her/model/introspection.rb:15:in `inspect'
    from [...]/gems/her-0.2/lib/her/model/introspection.rb:27:in `attribute_for_inspect'
    from [...]/gems/her-0.2/lib/her/model/introspection.rb:16:in `block in inspect'
    from [...]/gems/her-0.2/lib/her/model/introspection.rb:16:in `each'
    from [...]/gems/her-0.2/lib/her/model/introspection.rb:16:in `inject'
    from [...]/gems/her-0.2/lib/her/model/introspection.rb:16:in `inspect'
    from (irb):3
    from [...]/gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
    from [...]/gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
    from [...]/gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

The problem is that it tries to set t.user to a new instance of User, but passes nil to the constructor. Introspection#inspect then raises NoMethodError when accessing @data.inspect? because @data is nil.

I have a simple fix which I can give you a pull request for:

diff --git a/lib/her/model/relationships.rb b/lib/her/model/relationships.rb
index 5f98cbc..0489b65 100644
--- a/lib/her/model/relationships.rb
+++ b/lib/her/model/relationships.rb
@@ -16,7 +16,7 @@ module Her
           relationships.each do |relationship|
             name = relationship[:name]
             class_name = relationship[:class_name]
-            next unless data.include?(name)
+            next if data[name].blank?
             data[name] = case type
               when :has_many
                 Her::Model::ORM.initialize_collection(class_name, data[name])

With that patch applied the inspect method works fine again, and t.user returns nil.

However, this breaks a lot of tests which expect a null instance of a relationship class to be instantiated even if there is no data. Let me know your thoughts.

Thanks for the library though, it's going to be extremely useful!

test breakage under Faraday 0.9.x/1.0 (pre-release)

Hey, I've made some radical changes to the underlying builder/middleware system in Faraday. Her has just one test failure when run in legacy mode:

  1) Her::API initialization#setup takes custom options
     Failure/Error: @api.setup :foo => { :bar => "baz" }, :url => "https://api.example.com"
     NoMethodError:
       undefined method `foo=' for #<Faraday::ConnectionOptions:0x007ffabf31c538>
     # ./lib/her/api.rb:56:in `setup'
     # ./spec/api_spec.rb:34:in `block (4 levels) in <top (required)>'

Faraday 0.9 and up has replaced the nested hashes that Faraday::Connection.new takes in favor of Structs. The benefit is that misspelled options immediately raise exceptions, instead of subtly introducing bugs. The downside is that you can no longer pass custom options around.

Is Her relying on this functionality?

Multipart HTTP Requests with Her

Someone asked me a question via email in regard to Her’s ability to perform multipart HTTP requests, so I though I’d answer here too in case someone else has the same question.

Since Her is using the awesome Faraday library to make HTTP requests and since Faraday supports multipart requests… Her supports them too!

Here’s an example of how to use them:

Her::API.setup :url => 'http://api.example.com' do |connection|
  connection.use Faraday::Request::Multipart
  connection.use Her::Middleware::DefaultParseJSON
  connection.use Faraday::Adapter::NetHttp
end

class User
  include Her::Model
end

User.post_raw("/users",
  :foo => "bar",
  :image => Faraday::UploadIO.new('/Users/remi/Desktop/foo.jpg', 'image/jpeg'),
  :text => Faraday::UploadIO.new('/Users/remi/Desktop/foo.txt', 'text/plain')
) # User.post would work too but woul expect the API to return a resource Hash

Hope that helps someone out there! 😄

Allow means to specify alternate id

Ideally there would be a means to specify the id (such as self.primary_key in AR) as opposed to assuming it will be id. Many legacy systems don't have this as the field.
The current impact is realized when fetching an existing record, applying an update then saving. The record appears to be new because the id field is not present in the data hash.

Please forgive me if there is a preferred approach to detailing the issue or proposing fixes etc. I've not contributed to other Gems before so this is a first for me.

What would you feel about making the following additions to lib/her/model.rb


module Model
    extend ActiveSupport::Concern

    # Instance methods
    include Her::Model::ORM
    include Her::Model::Introspection
    include Her::Model::Paths

    # Class methods
    included do
      extend Her::Model::Base
      extend Her::Model::HTTP
      extend Her::Model::Relationships
      extend Her::Model::Hooks

      # add the following to allow each Her::Model to define it's own primary_key ========================
      cattr_accessor :primary_key
      @@primary_key = :id


      # Define default settings
      base_path = self.name.split("::").last.underscore.pluralize
      collection_path "#{base_path}"
      resource_path "#{base_path}/:id"
      uses_api Her::API.default_api
    end
  end

With this in place, all references to id can be replaced by primary_key.


class Facade::Person
  include Her::Model

  self.primary_key = :person_id

end

Token Authentication Middleware returns nill for @app

I hope I'm not being dense on this one, but I am trying to set up an api for App1, and using Her to call it from App2. However, when I try to send the json request, App2 fails with 'undefined method `call' for nil:NilClass'.

My api for App1 is pretty standard, I think, and the code from the readme seems to be perfect for it how it is.

App2 is running:

Ruby 1.8.7 ree 358, rails 3.2.6, her 0.3.1, faraday (came with her) 0.8.4, rvm 1.14.10
#app2/config/initializers/her.rb
class TokenAuthentication < Faraday::Middleware
  def initialize(app, options={})
    @options = options
  end

  def call(env)
    env[:request_headers]["X-API-Token"] = @options[:token] if @options.include?(:token)
    @app.call(env)
  end
end

$app2 = Her::API.new
$app2.setup :url => 'http://local.app1' do |connection| #local.app1 is all setup
  connection.use TokenAuthentication, :token => "token_stuff"
  connection.use Faraday::Request::UrlEncoded
  connection.use Her::Middleware::DefaultParseJSON
  connection.use Faraday::Adapter::NetHttp
end
#employee.rb
class Employee
  include Her::Model
  uses_api $app2
end
# rails c
1.8.7 :001 > e = Employee.find 1
NoMethodError: undefined method `call' for nil:NilClass
    from /var/www/app2/config/initializers/her.rb:16:in `call' # This is where @app.call(env) is
    from /home/username/.rvm/gems/ree-1.8.7-2012.02@app2/gems/faraday-0.8.4/lib/faraday/connection.rb:226:in `run_request'
    from /home/username/.rvm/gems/ree-1.8.7-2012.02@app2/gems/faraday-0.8.4/lib/faraday/connection.rb:87:in `get'
    from /home/username/.rvm/gems/ree-1.8.7-2012.02@app2/gems/her-0.3.1/lib/her/api.rb:71:in `send'
    from /home/username/.rvm/gems/ree-1.8.7-2012.02@app2/gems/her-0.3.1/lib/her/api.rb:71:in `request'
    from /home/username/.rvm/gems/ree-1.8.7-2012.02@app2/gems/her-0.3.1/lib/her/model/http.rb:13:in `request'
    from /home/username/.rvm/gems/ree-1.8.7-2012.02@app2/gems/her-0.3.1/lib/her/model/orm.rb:79:in `find'
    from (irb):1

So, where am I messing up? I must admit I am not very familiar at all with middleware or faraday, and I don't quite see where @app is supposed to be coming from.

Any help is appreciated, thanks!

Custom primary keys broke inheritance

class ApiBase
  include Her::Model
end

class User < ApiBase
  collection_path '/api/users'
end

We have models defined like this. In the ApiBase we have custom functionality that we want to provide to each model. Previously this worked fine, but the changes in a961557 broke this. Now when I try and get a User it makes the following request:

=> User.find(1)
GET /api/users/:

The issue seems to be that the primary key is set on the base class, and lost when it is inherited. We can avoid it by changing the base class to be like this, but it feels a bit nasty:

class ApiBase
  def self.inherited(base)
    base.send :include, Her::Model
  end
end

We haven't got around to it yet, but we have a few models that we need to consume using STI so I'm not sure how well that is going to behave.

Problems with the example

Hi,

I am trying to use the 'her' gem as it seems like a really good gem. However I can't even get the simplest thing to work. Here is the error I am getting

1.9.2p320 :001 > s = Fileflow::Student.find(1)
URI::InvalidURIError: query conflicts with opaque
    from /Users/ceicke/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/uri/generic.rb:521:in `check_query'
    from /Users/ceicke/.rvm/rubies/ruby-1.9.2-p320/lib/ruby/1.9.1/uri/generic.rb:540:in `query='
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/faraday-0.8.4/lib/faraday/connection.rb:277:in `build_exclusive_url'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/faraday-0.8.4/lib/faraday/request.rb:94:in `to_env'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/faraday-0.8.4/lib/faraday/connection.rb:225:in `run_request'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/faraday-0.8.4/lib/faraday/connection.rb:87:in `get'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/her-0.2/lib/her/api.rb:67:in `request'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/her-0.2/lib/her/model/http.rb:37:in `request'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/her-0.2/lib/her/model/orm.rb:53:in `find'
    from (irb):1
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/railties-3.0.10/lib/rails/commands/console.rb:44:in `start'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/railties-3.0.10/lib/rails/commands/console.rb:8:in `start'
    from /Users/ceicke/.rvm/gems/ruby-1.9.2-p320@intranet/gems/railties-3.0.10/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

My setup is pretty default:

# config/initializers/her.rb
Her::API.setup :url => "http://127.0.0.1:3003/api/v1/" do |connection|
  connection.use Faraday::BasicAuthentication.basic_auth("user","pass")
  connection.use Faraday::Request::UrlEncoded
  connection.use Her::Middleware::DefaultParseJSON
  connection.use Faraday::Adapter::NetHttp
end
module Fileflow
  class Student
        include Her::Model
  end
end

I'm suspecting that the URL is not correctly built, but I have no idea where to hook into...

Any help would be appreciated,
Christoph

Faraday connections can store default headers/params

You don't necessarily need middleware like this:

class MyAuthentication < Faraday::Middleware
  def call(env)
    env[:request_headers]["X-API-Token"] = "foobar"
    @app.call(env)
  end
end

With Faraday, you'd do this:

http = Faraday.new :url => 'http://api.foo.com', :headers => {'X-API-Token' => 'foo'}

# change it after initialization
http.headers['X-API-Token'] = 'foo'

Just general feedback, go ahead and close it if you want :)

Follow redirects vs DefaultParseJSON

In the rails world, you normally respond with a redirect after a successful POST/PUT to the actual resource (POST /users would redirect to /users/1). There is FaradayMiddleware::FollowRedirects which would allow following redirects. But this fails because Her::Middleware::DefaultParseJSON tries to parse the (empty) body of the response.

I think there are two possible solutions: DefaultParseJSON should respect the Content-Type and/or DefaultParseJSON should not try to parse empty body. What would be the preferred way? I'd like to fix this and submit a pull request.

Testing relationships?

How do you guys go about testing Her relationships?

Is there a better way than this? Or maybe you don't test them?

it "belongs to a Some" do
  some_relationship = { 
    class_name: "Some", 
    name: :some, 
    foreign_key: "some_id", 
    path: "/somes/:id" 
  }
  described_class.relationships.fetch(:belongs_to).should include(some_relationship)
end

Thanks.

non-nested models

Perhaps I'm dense, but I can't work out how to get Her to create relationships where the URLs are not nested - ie, User has_many Books, but the URL should be /books/:book_id, not /users/:id/books/:book_id. It looks like straight string concatenation in relationships.rb - am i missing the point somehow?

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.