如何与多个模型共享相同的视图?
How to share same view with multiple models?
我有多个模型,它们的索引视图几乎共享完全相同的代码和布局。
.../chocolates/index.html.erb
<h1 class="col-sm-12 head">Index Bases</h1>
<hr>
<% @chocolates.each do |chocolate| %>
<%= link_to chocolate do %>
<%= set_img(chocolate) %>
<% end %>
<ul>
<li><%= chocolate.name %></li>
<li><%= chocolate.position %></li>
</ul>
<hr>
<div>
<%= link_to chocolate do %>
<span class="glyphicon glyphicon-eye-open"></span>
<% end %>
<%= link_to edit_chocolate_path(chocolate) do %>
<span class="glyphicon glyphicon-edit"></span>
<% end %>
<%= link_to basis, method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</div>
<% end %>
<hr>
<%= link_to '+ Add New Chocolate', new_chocolate_path %>
.../sweets/index.html.erb
<h1 class="col-sm-12 head">Index Bases</h1>
<hr>
<% @sweets.each do |sweet| %>
<%= link_to sweet do %>
<%= set_img(sweet) %>
<% end %>
<ul>
<li><%= sweet.name %></li>
<li><%= sweet.position %></li>
</ul>
<hr>
<div>
<%= link_to sweet do %>
<span class="glyphicon glyphicon-eye-open"></span>
<% end %>
<%= link_to edit_sweet_path(sweet) do %>
<span class="glyphicon glyphicon-edit"></span>
<% end %>
<%= link_to sweet, method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</div>
<% end %>
<hr>
<%= link_to '+ Add New Sweet', new_sweet_path %>
还有更多模型共享相同的布局,我想我一直在重复自己,所以我创建了一个共享的局部变量,以在使用该布局的每个视图中呈现。
.../sweets/index.html.erb
<% render 'shared/indexGrid', dist: @sweets%>
.../views/shared/_indexGrid.html.erb
<% title = dist.class.name.underscore.tr('_', ' ').pluralize.split.map(&:capitalize).join(' ') %>
<% sing = dist.class.name.underscore %>
<h1>Index <% title %></h1>
<hr>
<% dist.each do |sing| %>
<%= link_to sing do %>
<%= set_img(sing) %>
<% end %>
<ul>
<li><%= sing.name %></li>
<li><%= sing.position %></li>
</ul>
<hr>
<div>
<%= link_to sing do %>
<span class="glyphicon glyphicon-eye-open"></span>
<% end %>
<%= link_to send("edit_#{sing.class.name.underscore}_path", sing) do %>
<span class="glyphicon glyphicon-edit"></span>
<% end %>
<%= link_to sing, class: 'square red', method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</div>
<% end %>
<hr>
<%= link_to "+ Add New #{title}", send("new_#{sing.class.name.underscore}_path"), { class: 'btn btn-success btn-block'} %>
但它似乎没有用,因为-我认为- dist.class.name
deasnt return 我期望的值但是 returns "active_record/relation"
。
我在编辑视图之前尝试过相同的方法并且它适用于 dist: @sweet
.
我想过使用布局,但它给我留下了与其他索引视图非常相似的大块代码。
我已经与您分享了我的尝试,问题是...
- 我的代码有什么问题以及如何修复它?
- 这种方法是否被认为是 DRY 代码的良好实践?如果不是,当这些模型几乎共享完全相同的代码和布局时,与多个模型共享相同视图代码的最佳方式是什么?
一个简单的解决方案是使用包含 class_name
作为参数的部分
<% render 'shared/indexGrid', dist: @sweets, class_name = "Sweets"%>
或者添加一些东西让你认出哪个是来源....
你可以试试model_name
<% title = dist.model_name.to_s.underscore.tr('_', ' ').pluralize.split.map(&:capitalize).join(' ') %>
或更好
<% title = dist.model_name.human.pluralize.titleize %>
应该也给你想要的。
和清理路线,你可以看看PolymorphicRoutes
http://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html
所以而不是
link_to send("edit_#{sing.class.name.underscore}_path", sing)
你可以使用像
这样的东西
link_to 'Edit, edit_polymorphic_path(sing)
这应该能很好地清理您的共享索引页。
您还可以考虑创建一个 title_for(例如 )助手,returns 标题。清理它,但不是 100% 需要。
-- 第 2 部分 --
这是个好主意吗?或许?没有答案怎么办?有很多因素。所有这些模型总是完全相同的可能性有多大?以后要做出不同的作品需要付出多少努力/多少工作?如果我有一堆基本相同的模型,并且总是有完全相同的索引页,我可能会考虑做类似的事情。同样的想法用于自动生成视图等的引擎/宝石/插件。所以我想如果它们总是一样的,并且你总是希望保持它们看起来一样,那么这样的东西是非常好的。
至于 collections 在你看@sweets 之类的东西时,它不是你模型的单个实例。它可能是一个ActiveRelation
。所以从 active_model
调用 model_name
不会有太大帮助。如果您查看 rails 部分指南,您将看到 render @collection
。这基本上只是迭代 collection 中的每个 object,为您查看 model_name,并将其传递给相应的部分以进行渲染。
因此,如果您有一个 @sweets
的 collection,其中有一堆 Sweet
object,rails 将迭代 collection。然后为您呈现 _sweet.html.erb
(遵循定位哪个部分的正常规则)。有了这个,你可以将你的 <% dist.each do |sing| %>
块调整为 <%=render dist%>
然后确保每个模型都有一个部分并且它可以以不同的方式渲染它们
我有多个模型,它们的索引视图几乎共享完全相同的代码和布局。
.../chocolates/index.html.erb
<h1 class="col-sm-12 head">Index Bases</h1>
<hr>
<% @chocolates.each do |chocolate| %>
<%= link_to chocolate do %>
<%= set_img(chocolate) %>
<% end %>
<ul>
<li><%= chocolate.name %></li>
<li><%= chocolate.position %></li>
</ul>
<hr>
<div>
<%= link_to chocolate do %>
<span class="glyphicon glyphicon-eye-open"></span>
<% end %>
<%= link_to edit_chocolate_path(chocolate) do %>
<span class="glyphicon glyphicon-edit"></span>
<% end %>
<%= link_to basis, method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</div>
<% end %>
<hr>
<%= link_to '+ Add New Chocolate', new_chocolate_path %>
.../sweets/index.html.erb
<h1 class="col-sm-12 head">Index Bases</h1>
<hr>
<% @sweets.each do |sweet| %>
<%= link_to sweet do %>
<%= set_img(sweet) %>
<% end %>
<ul>
<li><%= sweet.name %></li>
<li><%= sweet.position %></li>
</ul>
<hr>
<div>
<%= link_to sweet do %>
<span class="glyphicon glyphicon-eye-open"></span>
<% end %>
<%= link_to edit_sweet_path(sweet) do %>
<span class="glyphicon glyphicon-edit"></span>
<% end %>
<%= link_to sweet, method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</div>
<% end %>
<hr>
<%= link_to '+ Add New Sweet', new_sweet_path %>
还有更多模型共享相同的布局,我想我一直在重复自己,所以我创建了一个共享的局部变量,以在使用该布局的每个视图中呈现。
.../sweets/index.html.erb
<% render 'shared/indexGrid', dist: @sweets%>
.../views/shared/_indexGrid.html.erb
<% title = dist.class.name.underscore.tr('_', ' ').pluralize.split.map(&:capitalize).join(' ') %>
<% sing = dist.class.name.underscore %>
<h1>Index <% title %></h1>
<hr>
<% dist.each do |sing| %>
<%= link_to sing do %>
<%= set_img(sing) %>
<% end %>
<ul>
<li><%= sing.name %></li>
<li><%= sing.position %></li>
</ul>
<hr>
<div>
<%= link_to sing do %>
<span class="glyphicon glyphicon-eye-open"></span>
<% end %>
<%= link_to send("edit_#{sing.class.name.underscore}_path", sing) do %>
<span class="glyphicon glyphicon-edit"></span>
<% end %>
<%= link_to sing, class: 'square red', method: :delete, data: { confirm: 'Are you sure?' } do %>
<span class="glyphicon glyphicon-remove"></span>
<% end %>
</div>
<% end %>
<hr>
<%= link_to "+ Add New #{title}", send("new_#{sing.class.name.underscore}_path"), { class: 'btn btn-success btn-block'} %>
但它似乎没有用,因为-我认为- dist.class.name
deasnt return 我期望的值但是 returns "active_record/relation"
。
我在编辑视图之前尝试过相同的方法并且它适用于 dist: @sweet
.
我想过使用布局,但它给我留下了与其他索引视图非常相似的大块代码。
我已经与您分享了我的尝试,问题是...
- 我的代码有什么问题以及如何修复它?
- 这种方法是否被认为是 DRY 代码的良好实践?如果不是,当这些模型几乎共享完全相同的代码和布局时,与多个模型共享相同视图代码的最佳方式是什么?
一个简单的解决方案是使用包含 class_name
作为参数的部分
<% render 'shared/indexGrid', dist: @sweets, class_name = "Sweets"%>
或者添加一些东西让你认出哪个是来源....
你可以试试model_name
<% title = dist.model_name.to_s.underscore.tr('_', ' ').pluralize.split.map(&:capitalize).join(' ') %>
或更好
<% title = dist.model_name.human.pluralize.titleize %>
应该也给你想要的。
和清理路线,你可以看看PolymorphicRoutes
http://api.rubyonrails.org/classes/ActionDispatch/Routing/PolymorphicRoutes.html
所以而不是
link_to send("edit_#{sing.class.name.underscore}_path", sing)
你可以使用像
这样的东西link_to 'Edit, edit_polymorphic_path(sing)
这应该能很好地清理您的共享索引页。
您还可以考虑创建一个 title_for(例如 )助手,returns 标题。清理它,但不是 100% 需要。
-- 第 2 部分 --
这是个好主意吗?或许?没有答案怎么办?有很多因素。所有这些模型总是完全相同的可能性有多大?以后要做出不同的作品需要付出多少努力/多少工作?如果我有一堆基本相同的模型,并且总是有完全相同的索引页,我可能会考虑做类似的事情。同样的想法用于自动生成视图等的引擎/宝石/插件。所以我想如果它们总是一样的,并且你总是希望保持它们看起来一样,那么这样的东西是非常好的。
至于 collections 在你看@sweets 之类的东西时,它不是你模型的单个实例。它可能是一个ActiveRelation
。所以从 active_model
调用 model_name
不会有太大帮助。如果您查看 rails 部分指南,您将看到 render @collection
。这基本上只是迭代 collection 中的每个 object,为您查看 model_name,并将其传递给相应的部分以进行渲染。
因此,如果您有一个 @sweets
的 collection,其中有一堆 Sweet
object,rails 将迭代 collection。然后为您呈现 _sweet.html.erb
(遵循定位哪个部分的正常规则)。有了这个,你可以将你的 <% dist.each do |sing| %>
块调整为 <%=render dist%>
然后确保每个模型都有一个部分并且它可以以不同的方式渲染它们