0

Imagine a Rails project that looks up animal celeberties based on their names. This Rails app is backed by an external service that does the actual lookup. The service returns back results based on a key. For example, if I make a request to this external api like [GET] /animal?name=benji, I would get back something like {"type":"dog", "legs":"4", "tail-length":"short", "collar":"blue"}. However, if I pass in ...?name=flipper to the animal endpoint, I would get back {"type":"dolphin", "color":"gray", "food":"fish"}. (The data is returned in actual JSON or XML. I am just using pseudo code here to communicate the point.)

My first question is this... Given that the attributes of the return call vary based on data which is passed in, when unmarshaling a response (for lack of a better term) into a "model" object, does it make sense to implement some type of factory pattern (ala Design Patterns in Ruby, by Russ Olsen, Chapter 13) to create objects of an appropriate class? Are there other approaches that would make sense?

My next question is this, lets say that I want to display a list of all animals on a web page (using ERB templates.) Does it make sense to create different partial templates (eg _dolphin.html.erb and _dog.html.erb) and then put a case in the main list view that can deligate rendering each list item to an appropriate template.

For example:

list.html.erb...

  <ul>
  <% for animal in @animals.each %>
     <li>   
        <% if animal.type == 'dog' %>
          <%= render :partial => 'dog', :locals => {:animal => animal} %>
        <% elsif item.type == 'dolphin' %>
          <%= render :partial => 'dolphin', :locals => {:animal => animal} %>
        <% else %>
          <%= render :partial => 'generic_animal', :locals => {:animal => animal} %>
        <% end %>
      </li>          
  <% end %>
  </ul>

(Here animal.type=='dog' is intentional. I am not using a symbol (:dog) because the data returned back from the API is a string value, and it is used to populate the animal.type attribute. Bad, I know.)

The project that I am working on is using this approach right now. (Obivously, I have changed the elements/domain.) I am wondering if this is a valid approach, and/or if others have dealt with similar problems and how they went about it.

Thanks!

4

1 回答 1

0

我会说创建一个包含所有可能属性的单个模型和一个视图(不能是无限数;))。

然后你有一个

if attribute_x exists then
  display it
end

if attribute_y exists then
  display it
end

对于每个属性。

如果你为每只动物创建一个视图,这根本不会是 DRY,因为你会重复自己很多次,只知道每只动物都有最喜欢的食物和颜色等。另一个原因:如果 API 发生变化一点点,动物会聚集或失去你必须适应这种变化的属性。

只有一种观点,这一切都会好起来的。

如果你想非常确定你收集了所有属性,你可以在你的控制器中放置一个所有已知属性的数组,如果有未知的东西:将它写入日志文件。


如果您希望能够为某些动物显示完全不同的东西,我只会选择“每只动物一个视图”的方式。但是你也可以告诉你的控制器,如果name = 'Donkey Kong'. 你知道我的意思。

于 2013-03-01T17:13:34.407 回答