Render partials inside loop in Rails 5

2019-08-24 09:34发布

Question: How do I make a partial (that has to be generic) loop through different variables?

I have a tabbed page where I want to use a partial to avoid duplicating my HTML. The tabs are "Videos" and "Articles". It's the exact same HTML but I want to iterate through @videos for videos and @articles for articles.

The idea was to make the product partial completely generic and then somehow pass in @videos or @articles that I want to iterate through.

Partial: _product.html.slim

.col-md-5
  .thumbnail
    .thumb.spacer-sm
      - if product.image.blank?
        iframe allowfullscreen="" frameborder="0" mozallowfullscreen="" src="https://player.vimeo.com/product/#{product.vimeo_id}" webkitallowfullscreen=""
      - elsif product.vimeo_id.blank?
        = image_tag(product.image.url,
          class: 'img img-responsive img-rounded')
    .caption
      .content-group-sm.media
        .media-body
          h6.text-semibold.no-margin
            = product.name
          small.text-muted
            | by 
            = product.user.name
        - unless product.price.blank?
          h6.text-success.media-right.no-margin-bottom.text-semibold
            | $
            = product.price
      = product.description
    .panel-footer.panel-footer-transparent
      .heading-elements
        ul.list-inline.list-inline-separate.heading-text
          li
            = link_to 'Delete', product_path(product), method: :delete
          li
            = link_to 'Edit', edit_product_path(product)

HTML view rendering the partial:

 .page-container.spacer-minus
    .page-content
      .row
        .col-md-4
          .sidebar-default.sidebar-separate
            .sidebar-content
              .content-group
                .panel.no-border-radius-top
                  ul.navigation
                    li.navigation-header Navigation
                    li.active
                      a data-toggle="tab" href="#videos"
                        i.icon-video-camera2
                        | Videos
                    li
                      a data-toggle="tab" href="#articles"
                        i.icon-graduation
                        | Articles

        .col-md-8
          .tab-content
            #videos.tab-pane.fade.in.active
              .row
                - @videos.each do |product|
                  = render 'shared/product'

            #articles.tab-pane.fade
              .row
                - @articles.each do |product|
                  = render 'shared/product'

I just need my loop to understand what variable I want to iterate through. I cannot include @video or @article in the partial since that will defeat the purpose of having a generic partial.

With this implementation, I get the error: undefined local variable or method `product' for #<#<Class:0x007fc58053ae60>:0x007fc58884ea68>

2条回答
来,给爷笑一个
2楼-- · 2019-08-24 09:53

Hi this is pretty stuff if you want articles to come after the videos then try this.

= render partial: "product", collection: @videos 

= render partial: "product", collection: @articles

this will remove the loop from your main view but in your case you are not using locals try this

          .row
            - @videos.each do |video|
              = render 'shared/product', locals: {product: video}
          .row
            - @articles.each do |article|
              = render 'shared/product' , locals: {product: article}

It will work.

查看更多
ゆ 、 Hurt°
3楼-- · 2019-08-24 10:08

Try this code:

#videos.tab-pane.fade.in.active .row - 

@videos.each do |video| 

  = render 'shared/product', product: video 

#articles.tab-pane.fade .row -       

@articles.each do |article| 

 = render 'shared/product', product: article
查看更多
登录 后发表回答