我按照教程如何将第三方api与ruby集成在轨道上,但是我收到错误
未定义的方法`map'for
{“number”=> 12}允许:false>:ActionController :: Parameters
指向 request.rb
query_string = query.map{|k,v| "#{k}=#{v}"}.join("&")
完整代码
recipes_controller.rb
class RecipesController < ApplicationController
def index
@tag = query.fetch(:tags, 'all')
@refresh_params = refresh_params
@recipes, @errors = Spoonacular::Recipe.random(query, clear_cache)
end
def show
@recipe = Spoonacular::Recipe.find(params[:id])
end
private
def query
params.permit(:query).fetch(:query, {})
end
def clear_cache
params[:clear_cache].present?
end
def refresh_params
refresh = { clear_cache: true }
refresh.merge!({ query: query }) if query.present?
refresh
end
end
应用/服务/ spoonacular / recipes.rb
module Spoonacular
class Recipe < Base
attr_accessor :aggregate_likes,
:dairy_free,
:gluten_free,
:id,
:image,
:ingredients,
:instructions,
:ready_in_minutes,
:title,
:vegan,
:vegetarian
MAX_LIMIT = 12
CACHE_DEFAULTS = { expires_in: 7.days, force: false }
def self.random(query = {}, clear_cache)
cache = CACHE_DEFAULTS.merge({ force: clear_cache })
response = Spoonacular::Request.where('recipes/random', cache, query.merge({ number: MAX_LIMIT }))
recipes = response.fetch('recipes', []).map { |recipe| Recipe.new(recipe) }
[ recipes, response[:errors] ]
end
def self.find(id)
response = Spoonacular::Request.get("recipes/#{id}/information", CACHE_DEFAULTS)
Recipe.new(response)
end
def initialize(args = {})
super(args)
self.ingredients = parse_ingredients(args)
self.instructions = parse_instructions(args)
end
def parse_ingredients(args = {})
args.fetch("extendedIngredients", []).map { |ingredient| Ingredient.new(ingredient) }
end
def parse_instructions(args = {})
instructions = args.fetch("analyzedInstructions", [])
if instructions.present?
steps = instructions.first.fetch("steps", [])
steps.map { |instruction| Instruction.new(instruction) }
else
[]
end
end
end
end
应用/服务/ spoonacular / base.rb
module Spoonacular
class Base
attr_accessor :errors
def initialize(args = {})
args.each do |name, value|
attr_name = name.to_s.underscore
send("#{attr_name}=", value) if respond_to?("#{attr_name}=")
end
end
end
end
应用/服务/ spoonacular / request.rb
module Spoonacular
class Request
class << self
def where(resource_path, cache, query = {}, options = {})
response, status = get_json(resource_path, cache, query)
status == 200 ? response : errors(response)
end
def get(id, cache)
response, status = get_json(id, cache)
status == 200 ? response : errors(response)
end
def errors(response)
error = { errors: { status: response["status"], message: response["message"] } }
response.merge(error)
end
def get_json(root_path, cache, query = {})
query_string = query.map{|k,v| "#{k}=#{v}"}.join("&")
path = query.empty?? root_path : "#{root_path}?#{query_string}"
response = Rails.cache.fetch(path, expires_in: cache[:expires_in], force: cache[:force]) do
api.get(path)
end
[JSON.parse(response.body), response.status]
end
def api
Connection.api
end
end
end
end
应用/服务/ spoonacular / connection.rb
require 'faraday'
require 'json'
module Spoonacular
class Connection
BASE = 'https://spoonacular-recipe-food-nutrition-v1.p.mashape.com'
def self.api
Faraday.new(url: BASE) do |faraday|
faraday.response :logger
faraday.adapter Faraday.default_adapter
faraday.headers['Content-Type'] = 'application/json'
faraday.headers['X-Mashape-Key'] ='key'
end
end
end
end
感谢您的帮助。
答案 0 :(得分:1)
这里有两个不同的错误。
未初始化的常量Spoonacular :: Recipe :: Request
您可以通过明确设置Request
类的顶级范围来解决此问题:
::Request.where(...)
如果您将Request
文件保留在app/spoonacular/request.rb
中,则适用。但我建议将其移至app/services/spoonacular/
所有其他spoonacular
相关课程。因此,在这种情况下,您需要在class Request
中包围module Spoonacular
。之后你可以这样称呼它:
Spoonacular::Request.where(...)
同样适用于班级Connection
。
未定义的方法`map'允许{“number”=&gt; 12}: 假&gt;:ActionController的::参数
这个来自query
中的私人recipes_controller.rb
方法。 params
是ActionController::Parameters
个对象,为了从中检索值,您需要首先允许它们:
def query
params.permit(:query).to_h
end
现在它应该返回Hash
个对象。