Ruby on rails 未定义的方法“映射”api请求
我学习了如何将第三方api与RubyonRails集成的教程,但遇到了一个错误 未定义的方法“map” {number=>12}允许:false>:ActionController::Parameters 哪个指向request.rb 完整代码 配方控制器.rb app/services/spoonacular/request.rbRuby on rails 未定义的方法“映射”api请求,ruby-on-rails,ruby,api,faraday,mashape,Ruby On Rails,Ruby,Api,Faraday,Mashape,我学习了如何将第三方api与RubyonRails集成的教程,但遇到了一个错误 未定义的方法“map” {number=>12}允许:false>:ActionController::Parameters 哪个指向request.rb 完整代码 配方控制器.rb app/services/spoonacular/request.rb 谢谢您的帮助。这里有两个单独的错误 未初始化的常量Spoonacular::Recipe::Request 您可以通过显式设置请求类的顶级作用域来修复此问题: 如果
谢谢您的帮助。这里有两个单独的错误 未初始化的常量Spoonacular::Recipe::Request 您可以通过显式设置请求类的顶级作用域来修复此问题: 如果您将请求文件保存在app/spoonacular/Request.rb中,则此选项适用。但我建议把它移到app/services/spoonacular/上,你所有其他与spoonacular相关的课程都在那里。所以在这种情况下,您需要在模块Spoonacular中包围类请求。之后你可以这样称呼它:
Spoonacular::Request.where(...)
类连接也是如此
允许{number=>12}的未定义方法“map”:
false>:ActionController::参数
这个来自recipes_controller.rb中的私有查询方法。params是ActionController::Parameters对象,为了从中检索值,您需要首先允许它们:
def query
params.permit(:query).to_h
end
现在它应该返回Hash对象
关于那件事
在问题中包括这些文件的路径。您是否也尝试将请求移动到Spoonacular::Recipe命名空间下?如果它不应该存在,您是否尝试使用::Request引用全局范围。其中…?我打赌Request.rb的路径包含/spoonacular/recipe/so rails尝试基于该路径解析请求常量so did::Request。其中。。。工作我还建议将request.rb和connection.rb移到app/services/spoonacular/namespace。在这种情况下,你把它叫做Spoonacular::Request,你是说像这样?response=::Request.where'recipes/random',cache,query.merge{number:MAX_LIMIT}我将所有文件移动到spoonacular文件夹,现在我得到错误->无法自动加载常量Spoonacula::Request在移动请求后是否用模块spoonacular包围了类请求。rb?我做了如您所说的更改,但仍然存在相同的问题。我更新了问题。@Kristis我真的看不出你们做了什么更改。我在控制器查询方法和recipe.rb文件self.random方法中做了更改。另外,我在Spoonacular模块中圈出了connection和request类。@Kristis在您的问题中仍然有查询方法的旧版本。@Kristis Check out。它将帮助您了解您的第二个问题
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
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
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
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
::Request.where(...)
Spoonacular::Request.where(...)
def query
params.permit(:query).to_h
end