我有一个控制器有两个动作:“show”,“show_modify”。它们具有非常相似但略有不同的视图,即show_modify具有不同的div
类,具有额外的链接/按钮等等。
从我所看到的有几种方法可以在rails中实现这一点:
为这两个人制作一个模板,只需添加条件:
<% if param[:action]=="show_modify"> <% ... %> <% end %>
但是有很多不同之处,这看起来非常丑陋和重复,这也是对教会和国家分离的某种违反(我不是MVC专家......)
部分方式:对于每个显示不同的元素,创建两个部分,每个部分对应一个部分。观点看起来像这样:
# show_modify
render :partial '_general_stuff'
render :partial => '_blabla_show_modify'
# show
render :partial => '_general_stuff'
render :partial => '_blabla_show' `
然而,这将违反DRY,因为存在重叠因素。我可以继续制作更多的子部分,但它基本上都是乌龟 - 如果你不想重复自己,最终你必须去if / else。
与当地人的部分:
if show
render :partial = '_blabla', :locals => {:bckgrnd => 'blue', :button => 'yes' ....}
但这是另一个很好的解决方案....
还有更好的选择吗?可能content_for
?我有点像Rails noob +,所以我可能完全错过了一些东西......
答案 0 :(得分:0)
根据您的描述,这两个视图似乎不太相似,在整个视图中,所有类型的异常都是如此。因此,你的问题是许多if语句或部分不起作用。
是否无法以更好的匹配方式重构您的观点?例如,保持div类名相同,并根据您的视图切换CSS。然后使用部分视图方法可能会更好。特别是如果你还在这个局部视图之外移动链接(提交按钮?)并将其放在show_modify视图中。
答案 1 :(得分:0)
如果差异非常小,你可以使用你的第一个想法,但我宁愿做一些帮助:
def show_modify?
param[:action] == "show_modify"
end
然后在视图中:
<% if show_modify? %>
some html
<% end %>
...
<%= link_to "something", some_path if show_modify? %>
等等。
对于div类,我会使用辅助方法生成类名:
def set_class
return "first_class" if show_modify?
"second_class"
end
答案 2 :(得分:0)
尝试将对象扩展为视图模型。当您希望使用与业务域无关的内容扩展域对象时,这在ASP.NET MVC中非常常见。
class User < ActiveRecord::Base
# id, integer
# first_name, string
# last_name, string
# only put the business-y stuff here. validations, etc.
end
class ShowUserViewModel < User
def background_color
"#0000ff"
end
def template
"show"
end
end
class EditUserViewModel < User
def background_color
"#00ff00"
end
def template
"show_modify"
end
end
从控制器中,根据所采取的操作,返回相应的对象。视图模型仍然是“用户”,但它们补充了视图所需的更多信息。这实际上可以将大量if
和for
结构排除在视图之外。
答案 3 :(得分:0)
我处于类似情况。我正在考虑将我的观点分成两个完全不同的观点。这可能是最好的选择,如果两个视图随着年龄的增长而变得越来越不同,因为两个新视图将完全分离。如果您希望视图的重要块在show
和show_modify
之间保持不变,则此方法可能不太有用......