我有一个搜索表单,我使用YP(黄页)API,用Ruby编码,与Sinatra。
我已经设法连接所有的点得到搜索工作后端,但我有麻烦连接搜索表单到API调用。页面上的所有内容都显示正确,但是当我点击提交按钮时什么都没有显示。
我使用的代码如下:
require 'rubygems'
require 'sinatra'
require 'yp'
# index.rb
get "/" do
# Only run the search if both of our params are available
if params[:location] && params[:term]
client = Yp::Client.new(api_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
results = client.search(searchloc: params[:location], term: params[:term], listingcount: 1, sort: 'distance')
erb :index, :locals => {results: results}
end
__END__
@@index
<h1>YP Search</h1>
<form action="/" method="get">
Location: <input type="text" name="location"> <br />
Search Term: <input type="text" name="term" required> <br />
<input type="submit">
</form>
<% if results %>
<% results.each do |result| %>
# Print out the result info
<% end %>
<% else %>
# They haven't searched yet.
<% end %>
正如您所写的那样,您没有将结果传递给模板。块中的最后一个调用成为返回值,它是传递给客户端的主体,因此使用您的代码:
get "/" do
# Only run the search if both of our params are available
if params[:location] && params[:term]
client = Yp::Client.new(api_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
@results = client.search(searchloc: params[:location], term: params[:term], listingcount: 1, sort: 'distance')
end
这条线:
@results = client.search(searchloc: params[:location], term: params[:term], listingcount: 1, sort: 'distance')
变成主体。你想要的是呈现的模板作为最后一行,所以:
get "/" do
# Only run the search if both of our params are available
if params[:location] && params[:term]
client = Yp::Client.new(api_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
@results = client.search(searchloc: params[:location], term: params[:term], listingcount: 1, sort: 'distance')
erb :index
end
实例变量对模板是自动可见的,所以这就是你所需要做的。如果你想传递一个局部变量:
get "/" do
# Only run the search if both of our params are available
if params[:location] && params[:term]
client = Yp::Client.new(api_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
results = client.search(searchloc: params[:location], term: params[:term], listingcount: 1, sort: 'distance')
erb :index, :locals => {results: results}
end
,然后从模板中@results
变量的前面删除@
。
erb :index
是一个方法调用。它说"调用模板渲染器,使用ERB引擎并将:index
模板传递给它"。该方法的返回值是一个字符串。这个字符串可以在任何地方使用,就像一个普通的字符串一样,但你显然最有可能把它放在路由块的末尾,因为你想返回一个字符串。
你现在放置它的地方,在类体中,它只是一个方法调用,它的结果不去任何地方。这与以下操作相同:
get "/you/can/access/this" do
"and this would be the returned body"
end
get "/and/this" do
erb :index, :locals=>{:what_youd_see => "would be the template"}
end
"But this is just a string that no one can access, it gets called every time, but who is the receiver?"
把你的Sinatra应用想象成一个类,然后Ruby的常规规则就变得更清晰了:)
我克隆了你的Git仓库,发现了一些问题:
- 你不需要在gemspec中将rubygems列为依赖项。
- Shotgun没有在gemspec或Gemfile中作为开发依赖项列出。
- Rails即使不在项目中也被列出。
Gem::Specification.new do |gem|
#other code
gem.version = Yp::VERSION
gem.add_development_dependency "shotgun"
gem.add_dependency('faraday', ["< 0.8", ">= 0.6"])
gem.add_dependency('faraday_middleware', [">= 0.8"])
gem.add_dependency('sinatra')
end
以上就是我如何改变yp的。但是我个人不会把开发依赖放在gemspec文件中,而是放在Gemfile中。
# Gemfile
group :development do
gem "shotgun"
end
我认为这样更容易管理和更好地区分事物。我没有运行bundle install
,而是运行bundle install --binstubs --path vendor
,因为它将所有内容放在本地项目目录中。这样所有的项目都是相互隔离的,你会注意到你是否漏掉了什么。为了运行应用程序,我使用了bundle exec ruby index.rb
。
- index.rb 有语法错误
使用ruby -c filename
检查语法错误。当您在加载时遇到错误时,首先要尝试的是
- 在Ruby中你必须用
end
关闭if…else块。
如果没有给出参数,我还添加了一个选项,但是您也可以使用错误处理程序或将错误传递到模板中以通知用户。YMMV .
get "/" do
halt 400, "You need to supply a location and a term"
# Only run the search if both of our params are available
if params[:location] && params[:term]
client = Yp::Client.new(api_key: "e89cba4b974a122e408d1723626f3709")
results = client.search(searchloc: params[:location], term: params[:term], listingcount: 1, sort: 'distance')
end
erb :index, :locals => {results: results}
end
- 你已经硬编码了API密钥
我猜这应该是秘密。最好的办法可能是获得一个新的,不要硬编码它,也不要将它检入到Git中。我使用一个不被Git跟踪的文件,它被加载到环境变量中,例如
YAML.load_file("config/secret_settings.yml").each do |key,value|
ENV[key.upcase] = value
end
我将其添加到Rakefile中,并从机架文件运行应用程序,例如
namespace :app do
desc "Set up the environment locally"
task :environment do
warn "Entering :app:environment"
YAML.load_file("config/secret_settings.yml").each do |key,value|
ENV[key.upcase] = value
end
end
desc "Run the app locally"
task :run_local => "app:environment" do
exec "bin/rackup config.ru -p 4567"
end
end
从命令行:
bin/rake app:run_local
,你可能想要添加一个config.ru
.