我想以更好的方式将XML值从一个页面传递到另一个页面。
我从API得到这个XML值:
<hotelist>
<hotel>
<hotelId>109</hotelId>
<hotelName>Hotel Sara</hotelName>
<location>UK,london</location>
</hotel>
<hotel>
<hotelId>110</hotelId>
<hotelName>Radha park</hotelName>
<location>UK,london</location>
</hotel>
<hotel>
<hotelId>111</hotelId>
<hotelName>Hotel Green park</hotelName>
<location>chennai,India</location>
</hotel>
<hotel>
<hotelId>112</hotelId>
<hotelName>Hotel Mauria</hotelName>
<location>paris,France</location>
</hotel>
</hotelist>
我想经过一家旅馆:
<hotel>
<hotelId>112</hotelId>
<hotelName>Hotel Mauria</hotelName>
<location>paris,France</location>
</hotel>
转到下一页
我使用Nokogiri gem来解析XML。对于API下一次调用,我必须将一个酒店传递到下一页。哪个是最好的方法?
注:这只是一个样本。有很多信息与酒店捆绑在一起,包括可用房间、折扣等。
据我所知,您正在通过第三方服务搜索一些酒店,然后显示一个列表。用户单击某项后,将显示详细信息
最简单的方法是使用另一个API端点,它可以提供特定Hotel id的详细信息。我猜你正在处理一些非常糟糕的API,但事实并非如此。
还有其他几个选项(按复杂程度排序):
-
确实没有太多的数据,它应该适合一个简单的GET请求,所以您可以将各自的酒店信息编码到详细信息的URL参数中页面。假设您已经设置了资源充足的路由,并且已经将XML解析为一些Hotel模型/结构或类似的
@hotels
数组:<% @hotels.each |hotel| do %> <% # generates <a href=/hotels/112?hotelName=Hotel+Mauria&location=paris%2C+France'>Hotel Mauria</a> <%= link_to hotel.hotelName hotel_path(hotel.hotelId, hotelName: hotel.hotelName, location: hotel.location) %> <% end %>
-
将信息作为数据属性编码到各自的Hotel DOM元素中:
<div class="hotel" data-id="112" data-hotel-name="Mauria" ... />
然后在客户端呈现详细信息页面,完全不需要服务器,方法是订阅一个click事件,读取存储在各自数据属性中的信息,并用详细信息div替换列表。
如果第三方API是公开的,您甚至可以将搜索问题完全转移到客户端。
-
在服务器上引入搜索请求缓存。那就从缓存里挑一家酒店通过它的id。这将使您从Rails应用程序中节省大量第三方请求,如果部署在典型的多进程服务器上,这是Rails的弱点。
最简单的方法是将最后的搜索结果存储在用户会话中,但是可能会占用太多内存。如果您希望酒店信息不会频繁更改,则可以通过查询参数缓存它。你也可以使用一些智能缓存存储,如redis和索引整个酒店信息,而不是在缓存上执行搜索,只有在缓存失败的情况下才会使用第三方API。但是要记住,缓存很容易,过期很难。
"每个人都应该在Rails中使用低级缓存"对于实现缓存来说可能很有趣。
如果您不介意在查询参数中传递所有这些信息:
links = doc.xpath('//hotel').map do |hotel|
hash = Hash.from_xml(hotel.to_xml)
url_for({controller: 'x', action: 'y'}.merge(hash))
# or if you have your link as a string
# "#{link_string}?#{hash.to_param}"
end
如果你只想为一个酒店创建一个链接,提取相关的XML(例如,使用Uri回答中描述的过程),然后如上所述生成链接。
假设您在呈现当前页面之前已经准备好了API XML,您可以将相关的酒店数据呈现到表单字段中,以便您可以post
到下一个页面,如:
<%= fields_for :hotel do |hf| %>
<% hf.hidden_field :hotelId, value: hash['hotel']['hotelId'] %>
# ...
<% end %>
Mark Thomas提出了实现这一目标的最佳方法。
然而,如果你仍然需要在页面之间传递数据,你可以把所有的xml信息作为一个字符串放在会话变量中,并在下一页使用它