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

时间:2010-01-12 12:51:38

标签: ruby-on-rails views partials

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

从我所看到的有几种方法可以在rails中实现这一点:

  1. 为这两个人制作一个模板,只需添加条件:

    <% if param[:action]=="show_modify"> <% ... %> <% end %>
    

    但是有很多不同之处,这看起来非常丑陋和重复,这也是对教会和国家分离的某种违反(我不是MVC专家......)

  2. 部分方式:对于每个显示不同的元素,创建两个部分,每个部分对应一个部分。观点看起来像这样:

    # show_modify
    render :partial '_general_stuff'
    render :partial => '_blabla_show_modify'
    
    # show  
    render :partial => '_general_stuff'  
    render :partial => '_blabla_show'  `  
    

    然而,这将违反DRY,因为存在重叠因素。我可以继续制作更多的子部分,但它基本上都是乌龟 - 如果你不想重复自己,最终你必须去if / else。

  3. 与当地人的部分:

    if show  
         render :partial = '_blabla', :locals => {:bckgrnd => 'blue', :button => 'yes' ....}
    

    但这是另一个很好的解决方案....

  4. 还有更好的选择吗?可能content_for?我有点像Rails noob +,所以我可能完全错过了一些东西......

4 个答案:

答案 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

从控制器中,根据所采取的操作,返回相应的对象。视图模型仍然是“用户”,但它们补充了视图所需的更多信息。这实际上可以将大量iffor结构排除在视图之外。

答案 3 :(得分:0)

我处于类似情况。我正在考虑将我的观点分成两个完全不同的观点。这可能是最好的选择,如果两个视图随着年龄的增长而变得越来越不同,因为两个新视图将完全分离。如果您希望视图的重要块在showshow_modify之间保持不变,则此方法可能不太有用......