Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何将这个Ruby重写为更干爽、更符合Rails';最佳做法_Ruby On Rails - Fatal编程技术网

Ruby on rails 如何将这个Ruby重写为更干爽、更符合Rails';最佳做法

Ruby on rails 如何将这个Ruby重写为更干爽、更符合Rails';最佳做法,ruby-on-rails,Ruby On Rails,我敢肯定我已经打破了一些最佳实践,谁能给我一些指导,让我知道这段代码应该去哪里。如果不能改进(不太可能),请也告诉我:) 其目的是在年度“标题”下列出每年的所有活动。我稍后会整理输出 控制器只是用Activity.all证明@activities 编辑:我理解对助手的需要,但是向助手添加html是可以接受的,还是我需要在视图中这样做?if和else中都不应该出现常见的代码,因此您不必在其中重复 <% year = '' %> <% for activity in @a

我敢肯定我已经打破了一些最佳实践,谁能给我一些指导,让我知道这段代码应该去哪里。如果不能改进(不太可能),请也告诉我:)





其目的是在年度“标题”下列出每年的所有活动。我稍后会整理输出

控制器只是用Activity.all证明@activities


编辑:我理解对助手的需要,但是向助手添加html是可以接受的,还是我需要在视图中这样做?

if和
else
中都不应该出现常见的代码,因此您不必在其中重复

<% year = '' %>
<% for activity in @activities %>
  <% unless activity.date.strftime('%Y') == year %>
    <% year = activity.date.strftime('%Y') %>
    <%= year %>
    <br/>
  <% end %>
  <%= activity.date.strftime('%d %h') %>
  <%= activity.desc %>
  <br/>
<% end %>




编写覆盖这些分支的自动化测试,然后重构以将代码移动到助手方法中,并将其干燥:

def format_dates(activities)
  year = 0
  activities.map do |activity|
    activity_stuff = activity.date.strftime('%d %h ') + activity.desc
    if activity.date.year == year
      activity_stuff
    else
      year = activity.date.year
      [ activity.date.strftime('%Y'),
       activity_stuff ]
    end
  end.flatten
end
现在HTML.ERB代码如下所示:

<%=raw format_dates(@activities).join('<br/>') %>

记住“智能模型、精简控制器和哑视图”这一术语——助手实际上是模型方面的;您还可以使该代码成为
活动的静态方法

  • 请不要使用格式化的值作为比较的基础。许多日期/时间类(例如)都有一个
    year
    方法或类似方法,让您可以访问年份。您应该使用
    strftime
    进行显示,而不是逻辑
  • 在视图中实例化变量的那一刻,就是您知道应该将其移动到帮助器中的那一刻

    def activities_header(activities)
      activities.group_by { |activity| activity.date.year }.each do |year, activities_by_year|
        concat year
        concat content_tag(:br)
        activities_by_year.each do |activity|
          concat activity.date.strftime('%d %h')
          concat activity.desc
          concat content_tag(:br)
        end
      end
    end
    

  • 我还没有对此进行测试,但这里的想法是,从一开始,每年对活动进行分组。然后,您可以使用

    从您的视图中调用它,为什么不简单地
    一次呢start@DennyMueller这不会为同一年中的所有活动创建一个
    头。我在ruby中看不到太多for循环。为什么不使用
    each
    方法呢?是的,我稍后会切换到每个方法。如果我想在每个年度组周围放置一个div,是否可以将html放在帮助文件中,或者我需要做其他事情?它是
    raw
    ,所以只需使用
    activity.date.strftime(“%Y”)
    。这就是为什么strftime使用了
    %
    ,所以你可以根据需要弹奏他们的琴弦。我想他指的是每一年组(X年的活动),而不是将一年单独放在一个分区中。我认为用这个解决方案做起来不太容易。对你来说,同样的问题,如果我想在每个年度组中放置一个div,是否可以将html放在帮助文件中,或者我需要做其他事情?我怀疑在现代rails中,answer需要一个
    raw
    ,除非
    concat
    处理它。但你的问题和我的答案是一样的;见上文。第三个选项是Nokogiri::HTML::Builder,比如这里的错误否决答案:@user3052988您也可以对div使用content_标记,因为content_标记占用一个块。我建议将HTML放在助手中,因为您不希望助手的结构依赖于视图中的标记,反之亦然;将activities_头放在一个地方,即helper。@Phlip我很确定content_标记返回一个转义字符串,并且concat在这里附加到SafeBuffer。如果您将常规字符串与安全字符串混合使用,那么您是对的,您需要raw/html\u保护您的标记。不过,这和你的回答不一样;您的回答在助手(返回数组)和视图(使用
    加入数组)之间创建了一个不应该存在的依赖关系。如果您使用帮助器来处理activities头,请将所有标记放在那里,而不是其中的一部分。我还避免引入Nokogiri,因为它会产生额外的依赖,这是不必要的;我的修复说明了重构的“第一步”。后续传球将取决于只有OP才能看到的力。
    def activities_header(activities)
      activities.group_by { |activity| activity.date.year }.each do |year, activities_by_year|
        concat year
        concat content_tag(:br)
        activities_by_year.each do |activity|
          concat activity.date.strftime('%d %h')
          concat activity.desc
          concat content_tag(:br)
        end
      end
    end