Ruby on rails Rails:分离两个非常相似的视图的最佳方法是什么?

Ruby on rails Rails:分离两个非常相似的视图的最佳方法是什么?,ruby-on-rails,views,partials,Ruby On Rails,Views,Partials,我有一个控制器,它有两个动作:show,show\u modify。这些视图非常相似,但略有不同,即show_modify具有不同的div类,具有额外的链接/按钮等 据我所见,在rails中有几种方法可以实现这一点: 为两个模板制作一个模板,只需在其中添加条件: <% if param[:action]=="show_modify"> <% ... %> <% end %> 但这将违反DRY,因为存在重叠的元素。我可以继续制作更多的子部分,但基本上是海龟一路

我有一个控制器,它有两个动作:show,show\u modify。这些视图非常相似,但略有不同,即show_modify具有不同的div类,具有额外的链接/按钮等

据我所见,在rails中有几种方法可以实现这一点:

为两个模板制作一个模板,只需在其中添加条件:

<% if param[:action]=="show_modify"> <% ... %> <% end %>
但这将违反DRY,因为存在重叠的元素。我可以继续制作更多的子部分,但基本上是海龟一路走下去——如果你不想重复你自己,最终你必须去做

与本地人的部分对话:

if show  
     render :partial = '_blabla', :locals => {:bckgrnd => 'blue', :button => 'yes' ....}
但这是另一个lots-o-ifs解决方案


还有更好的选择吗?也许你会满足吗?我有点像Rails noob+,所以我可能遗漏了一些东西……

从您的描述来看,这两个视图似乎并不十分相似,在整个视图中,所有类型的例外都是存在的。所以你们的问题是很多if语句或部分语句都不起作用


难道不可能重构视图,使它们更好地匹配吗?例如,保持div类名不变,并根据视图切换CSS。然后使用局部视图方法可能会更好。特别是如果你也移动了链接提交按钮?在这个局部视图之外,将其放在show_modify视图中。

如果差异非常小,您可以使用您的第一个想法,但我更愿意提供一些帮助:

def show_modify?
  param[:action] == "show_modify"
end
然后在视图中:

<% if show_modify? %>
  some html
<% end %>
...
<%= link_to "something", some_path if show_modify? %>

尝试将对象扩展为视图模型。这在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结构出现在视图之外。

我也处于类似的情况。我正在考虑把我的观点分成两种完全不同的观点。这可能是最好的选择,如果这两个视图随着年龄的增长而变得越来越不相似,因为这两个新视图将完全解耦。如果希望视图的重要部分在show和show_modify之间保持不变,这种方法可能不太有用…

这不是一种非常干净的方法,因为应该使用模型从数据库中获取数据,以便在视图中使用。一个更简洁的解决方案是使用Helper方法,并根据viewI不知道的构造动态地将其功能添加到控制器中。它的可读性很强,产生的混乱也少很多。。。谢谢
def set_class
  return "first_class" if show_modify?
  "second_class"
end
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