【问题标题】:Quite new rails developer confused over content_tag and helpers相当新的 Rails 开发人员对 content_tag 和助手感到困惑
【发布时间】:2013-02-20 17:13:12
【问题描述】:

我正在尝试创建一个日历表来显示公司每个员工的每日可用性。我认为我需要的是一个带有每月天数的标题,然后是每个工作人员的一行(与天数一样多的单元格)。每个单元格的不同背景颜色将代表不同的可用性状态,并且工作人员会发生变化,所以我希望所有这些都是动态生成的。

在网上研究并以Ryan Bates' Railscast #213 (Calendars Revised) 为指导后,到目前为止,我已经设法生成了我的表格标题,该表格在每个单元格中显示了月份中的日期。

到目前为止,这就是我的代码:

module ReceptionHelper
def reception(date = Date.today, &block)
    Reception.new(self, date, block).table
end

class Reception < Struct.new(:view, :date, :callback)
    delegate :content_tag, to: :view

    def table
        content_tag :table, class: "calendar" do
            daysHeader
        end
    end

    def daysHeader
        last_day = date.end_of_month.strftime("%d").to_i
        (0..last_day).to_a.map { |day| content_tag :th, day }.join.html_safe
    end
end

现在,问题和困惑从这里开始:

  • 删除 &amp;block:callback 会删除 { ... } 功能,正如我发现的那样。我真的不能说我明白为什么。谁有好的解释?

  • 为什么上面的方法有效但我不能使用(..).each do 和下面的content_tag 块?

    (0..last_day).to_a.each do |day| 
        content_tag :th do
            day
        end
    end
    
  • 为了显示每个五线谱的行,我这样做了:

    def table
        content_tag :table, class: "calendar" do
            daysHeader + staffRows
        end
    end
    
    def staffRows
        staff.to_a.map { |staff| content_tag :tr, staff.name }.join.html_safe
    end
    

    我在Reception 类定义中添加了staff,并使用&lt;%= reception @staff %&gt; 调用 - 如果这不是一个很好的做法,请随时对我大喊:D

    但是,我没有让每个员工占一行,而是让所有成员的姓名在一行中并排排列,并位于标题的正上方。将 content_tag :tr 更改为 content_tag :td 会在最后一个标题单元格之后生成一个包含每个员工姓名的单元格。

如您所知,我对此非常迷茫,而且似乎我什至不清楚为什么按我想要的方式工作的部分是正确的。我希望这篇文章不会给人留下我希望把所有东西都放在盘子里的印象——我宁愿寻找可以帮助我理解的方向。 :)

编辑:

通过将staffRows 方法更改为以下方式,我取得了一些进展:

def staffRows
    staff.to_a.in_groups_of(1).map do |staff|
        content_tag :tr do
            staff.map { |room| content_tag :th, staff.name }.join.html_safe
        end
    end.join.html_safe
end

但是,这只会为每个房间生成一个单元格,而我想要一行与标题一样多的单元格。

【问题讨论】:

    标签: ruby-on-rails ruby block helper content-tag


    【解决方案1】:

    首先是 ruby​​ 约定:使用 2 个空格作为间距,使用 _ 作为方法名称。

    现在在编写复杂助手时认识你最好的朋友:concat。它的作用是将字符串直接输出到 ERB 缓冲区。向您展示和示例:

    def my_helper
      concat "hello world"
    end
    <% my_helper %>
    

    即使我们使用 &lt;% 而不是 &lt;%=,也会在 html 中输出 hello world

    在处理 helpers 中的块时这是非常重要的方法,因为这意味着您可以在块中多次调用 concat 并且两个字符串都会输出。这是一个例子:

    def my_helper
      content_tag :div do
        concat "Hello "
        concat "World"
        concat "!"
      end
    end
    <%= my_helper %>
    

    将输出&lt;div&gt;Hello World!&lt;/div&gt;。因此,使用相同的想法,您可以执行以下操作:

    def my_helper
      content_tag :ul do
        @people.each do |person|
          concat content_tag(:li, person.name)
        end
      end
    end
    <%= my_helper %>
    

    这会导致这样的结果:&lt;ul&gt;&lt;li&gt;John Doe&lt;/li&gt;&lt;li&gt;Mike Tyson&lt;/li&gt;&lt;/ul&gt;

    所以我会将days_helper 改写成这样的:

    def days_header
      (0..date.end_of_month.day).each { |day| concat content_tag(:th, day) }
    end
    

    staff_rows 方法做类似的事情,然后table 方法看起来就像这样:

    content_tag :table, class: "calendar" do
      days_header
      staff_rows
    end
    

    至于问题的回调部分:&amp;block 将传递给方法的块捕获到 Proc 对象中。该对象稍后可以传递给其他方法或直接调用。由于您没有使用回调对象,我只是建议将其删除。

    【讨论】:

    • 你好@Andrius,非常感谢你的回答,很抱歉没有早点回复 - 我从来没有收到通知。我记下了你写的东西,但我很喜欢你的 cmets 对我最终得到的解决方案,很快就会在这里发布代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 2011-01-24
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多