Ruby on rails 如何部分重构或使Haml文件的代码更加枯燥,Haml文件包含具有公共结构的选项卡

Ruby on rails 如何部分重构或使Haml文件的代码更加枯燥,Haml文件包含具有公共结构的选项卡,ruby-on-rails,ruby,reactjs,haml,Ruby On Rails,Ruby,Reactjs,Haml,我在一个RubyonRails 4.2.10项目中开发,我被要求重构一个面板,其中包含选项卡,以更好的方式划分为部分,全部内置Haml。我这么做了,但他们还是说我需要做得更好,尤其是这个文件: .dashboard_tabs .dashboard_tab.active{ data: { tab: 'problems' } } - shipments_count = problem_shipments.try(:count) || 0 %h2 Problems .bad

我在一个RubyonRails 4.2.10项目中开发,我被要求重构一个面板,其中包含选项卡,以更好的方式划分为部分,全部内置
Haml
。我这么做了,但他们还是说我需要做得更好,尤其是这个文件:

.dashboard_tabs
  .dashboard_tab.active{ data: { tab: 'problems' } }
    - shipments_count = problem_shipments.try(:count) || 0
    %h2 Problems
    .badge.danger{ class: [shipments_count.zero? && 'empty'] }= shipments_count

  .dashboard_tab{ data: { tab: 'created' } }
    - shipments_count = shipments.try(:count) || 0
    %h2 Created
    .badge{ class: [shipments_count.zero? && 'empty'] }= shipments_count

  .dashboard_tab{ data: { tab: 'requests' } }
    - shipments_count = shipment_requests.try(:count) || 0
    %h2 RFQ
    .badge{ class: [shipments_count.zero? && 'empty'] }= shipments_count

  .dashboard_tab{ data: { tab: 'pickups' } }
    - shipments_count = pickups.try(:count) || 0
    %h2 Pickup request
    .badge{ class: [shipments_count.zero? && 'empty'] }= shipments_count
评论是“这些标签似乎有很多共同点需要提取”,所以我不知道如何让它像我被问到的那样干燥

希望能得到一些好的建议

与此相关的其他文件如下:

索引

分批装运

%tr
  %td
    = shipment.customer_name_for_company(company_id: current_company.id)
  %td.id
    = link_to(shipment.unique_shipment_id, companies_shipment_path(shipment))
  %td.date
    = shipment.shipping_date
  %td
    = shipment.carrier_product.suffixed_name
  %td
    = render("components/shared/contact", contact: shipment.sender)
  %td
    = render("components/shared/contact", contact: shipment.recipient)
  %td.awb
    = render(partial: "components/shared/carrier_products/awb", locals: { shipment: shipment })

- if shipment.description.present?
  %tr.description
    %td{ :colspan => "7" }= shipment.description
部分拾取

%tr
  %td
    = pickup.customer_name
  %td.id
    = link_to(pickup.unique_pickup_id, companies_pickup_path(pickup))
  %td.date
    = pickup.pickup_date
  %td
    = pickup.from_time
  %td
    = pickup.to_time
  %td
    = pickup.description
分批装运请求

%tr
  %td
    = link_to(shipment_request.shipment.unique_shipment_id, companies_shipment_request_path(shipment_request))
  %td
    = shipment_request.shipment.shipping_date
  %td
    = "#{shipment_request.shipment.sender.company_name},"
    %br/
    = shipment_request.shipment.sender.country_name
  %td
    = "#{shipment_request.shipment.recipient.company_name},"
    %br/
    = shipment_request.shipment.recipient.country_name
  %td
    = suffixed_name(name: shipment_request.shipment.carrier_product.name, company: shipment_request.shipment.company)

- if shipment_request.shipment.description.present?
  %tr.description
    %td{ :colspan => "5" }= shipment_request.shipment.description

我对HAML不是很有经验,但我认为他们所说的“这些选项卡似乎有很多共同点需要提取”的意思是,您或多或少都在为不同的变量编写相同的代码

您可以做的是将唯一的数组变量传递给您的部分选项卡,例如:

render(partial: 'shipment_tabs', 
  locals: { data: [
    { name: "Problems", tab: "problems", count: @view_model.problem_shipments.try(:count) || 0 },
    { name: "Created", tab: "created", count: shipments.try(:count) || 0 },
    { name: "RFQ", tab: "requests", count: shipment_requests.try(:count) || 0 },
    { name: "Pickup request", tab: "pickups", count: pickups.try(:count) || 0 }
  ] }
)
在这个数组的部分循环中

.dashboard_tabs
  - data.each do |entry|
    .dashboard_tab.active{ data: { tab: entry["tab"] } }
      %h2 #{entry["name"]}
      .badge.danger{ class: [entry["count"].zero? && 'empty'] }= entry["count"]

如果您定义了部分
\u仪表板\u选项卡
,如下所示

.dashboard_tab{class: active ? 'active' : '', data: {tab: tab_name}
  - shipments_count = shipments.try(:count) || 0
  %h2= title 
  .badge{ class: [shipments_count.zero? && 'empty'] }= shipments_count
然后可以按如下方式重写原始视图:

.dashboard_tabs
  = render 'dashboard_tab', active: true, tab_name: 'problems', |
                            title: 'Problems', shipments: problem_shipments
  = render 'dashboard_tab', active: false, tab_name: 'created', | 
                            title: 'Created', shipments: shipments
  = render 'dashboard_tab', active: false, tab_name: 'requests', |
                            title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', active: false, tab_name: 'requests', |
                            title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', active: false, tab_name: 'pickups', |
                            title: 'Pickup request', shipments: pickups
 - active = local_assigns.has_key?(:active) ? active : false 
 - badge_class = local_assigns.has_key?(:badge_class) ? badge_class : ''
 .dashboard_tab{class: active ? 'active' : '', data: {tab: tab_name}
   - shipments_count = shipments.try(:count) || 0
   %h2= title 
   - badge_classes = [badge_class] 
   - badge_classes << 'empty' if shipments_count.zero?
   .badge{ class: badge_classes.join(" ") }= shipments_count
.dashboard_tabs
  = render 'dashboard_tab', active: true, badge_class: 'danger', tab_name: 'problems', |
                            title: 'Problems', shipments: problem_shipments
  = render 'dashboard_tab', tab_name: 'created',  title: 'Created', shipments: shipments,
  = render 'dashboard_tab', tab_name: 'requests', title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', tab_name: 'requests', title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', tab_name: 'pickups',  title: 'Pickup request', shipments: pickups
这是一个开始。我们现在错过了问题标识的
danger
类,我们重复
active
,而我们只想首先激活(默认值为false)

因此,我们可以通过添加一个额外的badge类(并使其可选)和使活动状态也可选,来进一步优化我们的部分状态

因此,我们将部分调整如下:

.dashboard_tabs
  = render 'dashboard_tab', active: true, tab_name: 'problems', |
                            title: 'Problems', shipments: problem_shipments
  = render 'dashboard_tab', active: false, tab_name: 'created', | 
                            title: 'Created', shipments: shipments
  = render 'dashboard_tab', active: false, tab_name: 'requests', |
                            title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', active: false, tab_name: 'requests', |
                            title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', active: false, tab_name: 'pickups', |
                            title: 'Pickup request', shipments: pickups
 - active = local_assigns.has_key?(:active) ? active : false 
 - badge_class = local_assigns.has_key?(:badge_class) ? badge_class : ''
 .dashboard_tab{class: active ? 'active' : '', data: {tab: tab_name}
   - shipments_count = shipments.try(:count) || 0
   %h2= title 
   - badge_classes = [badge_class] 
   - badge_classes << 'empty' if shipments_count.zero?
   .badge{ class: badge_classes.join(" ") }= shipments_count
.dashboard_tabs
  = render 'dashboard_tab', active: true, badge_class: 'danger', tab_name: 'problems', |
                            title: 'Problems', shipments: problem_shipments
  = render 'dashboard_tab', tab_name: 'created',  title: 'Created', shipments: shipments,
  = render 'dashboard_tab', tab_name: 'requests', title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', tab_name: 'requests', title: 'RFQ', shipments: shipment_requests
  = render 'dashboard_tab', tab_name: 'pickups',  title: 'Pickup request', shipments: pickups

好的,有道理,但是第一个建议我必须为它制作一个新的部分,否则我会将我首先共享的文件更改为该部分?就像你的两个建议都将被添加到同一个文件中一样?第一个建议只是从第17行的
索引中的部分调用中进行编辑,我已经将代码的其余部分抽象到这一行。badge.danger{class:[条目[“count”].zero?&&&“empty”]}=entry[“count”]对于nil:nilclass,我现在得到了一个错误未定义的方法'zero'。以上最后两行代码中的第一行。第一个是我应该在部分中定义什么,第二个是我将在索引中定义什么?你能在我的文件中添加更改吗?这样我就可以知道应该在哪里进行更改了?我知道第一个用于部分,第二个用于索引是否正确?
装运。try(:count)
将创建一个N+1查询问题,因为
count
从…
查询发出一个
选择count(*)。您应该改为使用
.size
,因为如果已加载集合或计数器缓存,它将使用
.length
。您也可以使用
any?
none?
来遵从
.size
。也可以使用
。try
可能不需要,因为您处理的是空集合,而不是零值(希望如此)。您好@jakub您理解正确(不确定您如何理解它)好的,但在第一部分,我从编辑器内联代码中得到了错误,因为它说的不是Haml格式的,或者与之相关