Html 使用搜索结果中的Ruby on Rails显示列表/或表
RubyonRails的新特性。提交搜索参数后,我想更新new.html.erb视图以显示album_controller.rb中的搜索结果。我可以创建一个隐藏元素,然后从控制器中显示它吗?搜索结果是字符串数组的数组 我的目标是显示可供选择的相册列表(从HTTPGET请求获得),然后让用户选择要进行的搜索结果 new.html.erbHtml 使用搜索结果中的Ruby on Rails显示列表/或表,html,ruby-on-rails,ruby,Html,Ruby On Rails,Ruby,RubyonRails的新特性。提交搜索参数后,我想更新new.html.erb视图以显示album_controller.rb中的搜索结果。我可以创建一个隐藏元素,然后从控制器中显示它吗?搜索结果是字符串数组的数组 我的目标是显示可供选择的相册列表(从HTTPGET请求获得),然后让用户选择要进行的搜索结果 new.html.erb <h4>Search for Album</h4> <%= form_with(url: "/albums/search", me
<h4>Search for Album</h4>
<%= form_with(url: "/albums/search", method: "get") do %>
<%= label_tag(:q, "Search for: ") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
在Rails中,您希望构建包含最少代码的瘦控制器,并且唯一的公共方法应该是与路由对应的操作。这是因为众所周知,控制器很难测试,而且膨胀很快就会成为一个问题 HTTP调用、批处理和其他此类任务不属于控制器。尤其是当它们触及应用程序边界时。相反,您希望创建一个处理HTTP调用的客户机对象,以及封装数据并为应用程序规范化数据的模型 因此,让我们从HTTP调用开始:
# app/clients/audio_scobbler_client.rb
class AudioScrobblerClient
include Httparty
format :json
base_uri "http://ws.audioscrobbler.com/2.0/"
def initialize(api_key:)
@base_opts = {
api_key: api_key,
format: "json" # may be redundant
}
end
def album_search(query, limit: 15)
self.class.get(
@base_opts.reverse_merge(
method: 'album.search',
limit: limit
)
)
end
end
这为您提供了一个可以与控制器分开测试的对象,并消除了使用字符串连接构造查询字符串的混乱(永远不要这样做)。它通过执行HTTP请求返回JSON,仅此而已
然后创建一个表示应用程序中搜索结果的模型。记住,持久性不是MVC中模型的唯一角色
# app/models/album.rb
class Album
include ActiveModel::Model
include ActiveModel::Attributes
attr :artist, String
attr :name, String
attr :image, String
end
现在,让我们在混合中再抛出一个对象—一个执行API调用并规范化值的服务对象:
# app/services/audio_scrobbler_search.rb
class AudioScrobblerSearch
def perform(query, **options)
api_key = ENV["AUDIOSCROBBER_API_KEY"] # or use the encrypted secrets.
json = AudioScrobblerClient.new(api_key: api_key).album_search(query, options)
json.dig("results", "albummatches", "album").map do |result|
# I have no idea what api response looks
# like but I have no doubt that you can figure this part out
Album.new(
artist: result["name"],
name: result["name"],
image: result["image"]
)
end
end
end
然后让我们消除控制器中的所有膨胀:
class AlbumsController < ApplicationController
# you don't really need the new action at all since a search form can just loop back on itself
# GET /albums/search?q=believe
def search
@search_query = params[:q]
if @search_query
@albums = AudioScrobblerSearch.perform(query)
end
end
end
class AlbumsController
并在视图中列出相册:
<h4>Search for Album</h4>
<%= form_with(url: "/albums/search", method: "get") do %>
<%= f.label(:q, "Search for: ") %>
<%= f.text_field(:q, value: @search_query) %>
<%= f.submit("Search") %>
<% end %>
<% if @albums %>
<table>
<thead>
<tr>
<th>Image</th>
<th>Artist</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<% @albums.each do |album| %>
<tr>
<td><%= tag.img src: album.image, alt: "Cover art for #{album.name}" %></td>
<td><%= album.artist %></td>
<td><%= album.name %></td>
</tr>
<% end %>
</tbody>
</table>
<% elsif @search_query.present? %>
<p>No results to display :(</p>
<% end %>
搜索相册
形象
艺术家
名称
没有要显示的结果:(
如果您想在查询中提交一个特定于某个相册的搜索。为什么不这样做:album.where(title:“inquery\u data”)
尚未创建相册obj。我想显示一个可能的相册列表以供选择(从http get请求获得),然后让用户选择要进行的搜索结果。我不太了解这里的流程。你想给他们一个相册列表,让他们从中选择,然后搜索相册选择导致的内容吗?似乎有点过于复杂。抱歉,如果我不明确,第一次发布。我想在数据库。流程如下:搜索唱片集(通过音乐api),http get请求返回json,将json解析为15个搜索结果,向用户显示搜索结果(我现在遇到了问题),然后最后让用户选择要添加到数据库的搜索结果。在将json放入视图时遇到问题吗?请注意,这个答案只是为了概述一般方法,我实际上根本没有测试api调用。您需要一些程序集,它很可能包含多个错误。谢谢您或者详细的答案,我现在正在看。我有一个问题。在audio_scrobbler_client中,“self.get”的目的是什么。我在这一点上得到了一个命名错误。同样在视图中,我看到您在@albums中迭代。但我不确定如何创建专辑列表。在audio_scrobbler_search.rb中,是否有Album.new()创建一个新的album对象并将其附加到列表中?否-album。新建(…)
只创建album的一个实例。查看它上面的行json.dig(“结果”、“albummatches”、“album”)
获取键obj[“结果”][“albummatches”][“album”]
。遍历数组并返回一个包含块返回值的新数组。for循环除ruby初学者外,任何人都不使用。很抱歉,它应该是self.class.get
调用HTTParty.get
。
class AlbumsController < ApplicationController
# you don't really need the new action at all since a search form can just loop back on itself
# GET /albums/search?q=believe
def search
@search_query = params[:q]
if @search_query
@albums = AudioScrobblerSearch.perform(query)
end
end
end
<h4>Search for Album</h4>
<%= form_with(url: "/albums/search", method: "get") do %>
<%= f.label(:q, "Search for: ") %>
<%= f.text_field(:q, value: @search_query) %>
<%= f.submit("Search") %>
<% end %>
<% if @albums %>
<table>
<thead>
<tr>
<th>Image</th>
<th>Artist</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<% @albums.each do |album| %>
<tr>
<td><%= tag.img src: album.image, alt: "Cover art for #{album.name}" %></td>
<td><%= album.artist %></td>
<td><%= album.name %></td>
</tr>
<% end %>
</tbody>
</table>
<% elsif @search_query.present? %>
<p>No results to display :(</p>
<% end %>