简体   繁体   中英

How to use faraday in Ruby on Rails?

First of all, I must say I'm just learning Ruby on Rails. I'm trying to get droplets list from Digital Ocean with faraday.

Here is my code:

module DropletsHelper
 require 'faraday'
 require 'json'

 @token = ENV["DO_TOKEN"]

 @conn = Faraday.new(:url => 'https://api.digitalocean.com', :ssl => {:verify => false})

 def droplets_all
   request = @conn.get do |req|
   req.url '/v2/droplets'
   req.headers['Authorization'] = @token
  end

  droplets = JSON.parse(request.body)
  droplets = droplets["droplets"]
  return droplets
 end
end

This code returns just #<Faraday::Connection:0x007fc3574b4f98> And in application I get an error: undefined method 'get' for nil:NilClass

What am I doing wrong? This code is perfectly working in irb.

Thank you.

This is a friendly reminder that you cannot pretend to use Rails, without learning the basics of Ruby. This issue is not a Rails problem, it's a Ruby problem.

There are several issues with your code.

  1. First, you use a module. A module cannot be instantiated (only a class), but your code uses @instance variables (which is a kind of contradiction).

  2. You placed the initialization code in the Module context, which is valuated when the Ruby code is parsed, not when it is executed.

The most simple solution is to change the code to be evaluated in a method.

require 'faraday'
require 'json'

module DropletsHelper

 def droplets_connection
   Faraday.new(:url => 'https://api.digitalocean.com', :ssl => {:verify => false})
 end

 def droplets_all
   request = droplets_connection.get do |req|
     req.url '/v2/droplets'
     req.headers['Authorization'] = ENV["DO_TOKEN"]
   end

   droplets = JSON.parse(request.body)
   droplets["droplets"]
 end
end

I assume that's a Rails helper that is going to be executed in a view.

The best solution, however, would be to extract the code in lib in a custom library, and just reference a simple execution in the helper. In this way, you can unit test the library more easily without the need to bootstrap a full Rails view stack.

Last but not least

:ssl => {:verify => false}

is a very bad idea. You should care about security.

I'm not a Ruby developer but the error seems very clear. @conn is nil ( NULL ), and of course you cannot access to any method. You should check @conn before use it. Probably there is somethin wrong here:

@conn = Faraday.new(:url => 'https://api.digitalocean.com', :ssl => {:verify => false})

because it is returning nothing

@conn and @token in your droplets_all method are not the same as @token and @return in line 5 and 7.

@conn and @token in droplets_all are instance variables that hold values bound to an instance of DropletsHelper (an instance of a Class that includes DropletsHelper, more precisely).

@token and @return in line 5 and line 7 are not. They are instance variables bound to DropletsHelper, which is an instance of Module class.

I think the easiest way to fix the problem is to change drorplets_all to a class method.

def self.droplets_all
...
end

Or you can set @conn and @token inside DropletsHelper. Be careful not to initialize them every time you call droplets_all.

def droplets_all
  @token ||= ENV["DO_TOKEN"]

  @conn ||= Faraday.new(...)

  ...
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM