我遵循教程如何将第三方API与Ruby集成在Rails上,但我遇到了一个错误
未定义的方法"地图"
{" number" => 12}允许:false>:actioncontroller ::参数
指向 request.rb
query_string = query.map{|k,v| "#{k}=#{v}"}.join("&")
完整代码
regece_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
app/services/spoonacular/coppes.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
app/services/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
app/services/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
app/services/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
感谢您的任何帮助。
您在这里有2个单独的错误。
非初始化的常量spoonacular :: copipe ::请求
您可以通过明确设置Request
类的顶级范围来解决此问题:
::Request.where(...)
如果将Request
文件保存在app/spoonacular/request.rb
中,则适用。但是我建议将其移至app/services/spoonacular/
,其中所有其他相关类别的其他spoonacular
。因此,在这种情况下,您需要在module Spoonacular
中环绕class Request
。之后,您可以这样称呼:
Spoonacular::Request.where(...)
类别Connection
的同样也是如此。
因此,关于范围分辨率运算符的答案
未定义的方法`{" number" => 12}允许: false>:ActionController ::参数
这个来自recipes_controller.rb
中的私有query
方法。params
是ActionController::Parameters
对象,为了从中检索值,您需要首先允许它们:
def query
params.permit(:query).to_h
end
现在它应该返回Hash
对象。
这是关于
的详细答案Rubyonrails指南有关强参数的指南