簡體   English   中英

如何迭代以查找表中是否存在任何記錄

[英]How iterate to find if any record in a table exists

Rails 的新手不確定我是否正在解決這個問題。 所以我通過 sql lite 有兩個表的數據庫。 酒吧和評論。 酒吧的 id 是評論的外鍵。

    create_table "reviews", force: :cascade do |t|
    t.string "picture"
    t.integer "bar_id"
    t.boolean "flagged_innapropriate"
    t.boolean "moderated"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["bar_id"], name: "index_reviews_on_bar_id"
  end

  create_table "bars", force: :cascade do |t|
    t.boolean "flagged_innapropriate"
    t.string "picture"
    t.boolean "moderated"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

我的導航欄上有一個部分,它在那里迭代並找到所有沒有評論的欄。

    <div class="top-text">
  <p>Be the first to review these bars! </p>
</div>

<div id="norev-container">

  <% @bars.each do |bar| %>
    <% if bar.name? && !bar.flagged_innapropriate && bar.reviews.length == 0 %>

      <div class="bar-container">
        <%= link_to image_tag(bar.picture.thumb.url), %`/bars/#{bar.id}/reviews/new`%>
      </div>

    <% end %>

  <% end %>

</div>

<%= javascript_pack_tag 'norev' %>

這很好用。 我也有一個導航欄。

<!DOCTYPE html>
<html>
  <head>
    <title>Bar Reviews</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= favicon_link_tag asset_path('favicon.ico') %>

</head>

  <body>
  <a href="/">
        <h1 id="title-top">
            Bar Reviews
        </h1>
      </a>
    <header>
      <nav class="navBar">
        <%= link_to "Home", root_path %>
        <%= link_to "Bars", bars_path %>
        <%= link_to "No Reviews", bars_norev_path %>
        <%= link_to "About", pages_about_url %>
      </nav>
    </header>

    <%= yield %>
  </body>

</html>

當沒有沒有評論的酒吧時,我希望隱藏“無評論”頁面的鏈接。 但是我無法理解我將如何遍歷表格以找出這一點。 有人指出我正確的方向嗎?

這通常是您希望對數據庫查詢執行的操作 不是通過在 Ruby 中遍歷表中的所有記錄。

可以使用左外連接來獲取連接表中沒有行的記錄:

@bars = Bar.left_joins(:reviews)
           .where(flagged_innapropriate: false) # make sure you add a default to the column!
           .where.not(name: nil) # smelly - this should be handled by a validation?
           .where(reviews: { id: nil })

這是一個邪惡的XY 問題 您不想知道如何“如何迭代以查找表中是否存在任何記錄”。 您想知道“如何有條件地生成鏈接?”

在您的情況下,只需執行以下操作:

<!DOCTYPE html>
<html>
  <head>
    <title>Bar Reviews</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= favicon_link_tag asset_path('favicon.ico') %>

</head>

  <body>
  <a href="/">
        <h1 id="title-top">
            Bar Reviews
        </h1>
      </a>
    <header>
      <nav class="navBar">
        <%= link_to "Home", root_path %>
        <%= link_to "Bars", bars_path %>
        <%= link_to("No Reviews", bars_norev_path) if @bars_needing_review.any? %>
        <%= link_to "About", pages_about_url %>
      </nav>
    </header>

    <%= yield %>
  </body>

</html>

自然,您需要在控制器中的適當位置設置@bars_needing_review變量(可能在ApplicationController - 視情況而定)。 一些東西,也許像:

@bars_needing_review = Bar.with_name.not_flagged_as_inappropriate.without_any_reviews

這意味着您所設置的with_namenot_flagged_as_inappropriatewithout_any_reviews在你的方法Bar類,是這樣的:

class Bar < ApplicationRecord

  class << self 

    def with_name
      where.not(name: nil)
    end

    def not_flagged_as_inappropriate
      where.not(flagged_inappropriate: true)
    end

    def without_any_reviews
      left_joins(:reviews).where(reviews: {id: nil})
    end

  end

end

這里有一個說明......有人會過來說那些應該是范圍,而不是類方法。 他們不一定是錯的。 這是一些意見的問題,你應該做讓你快樂的事情。 如果那種東西讓你的船漂浮,那么可能是這樣的:

class Bar < ApplicationRecord

  scope :with_name,                     -> { where.not(name: nil) }
  scope :not_flagged_as_inappropriate,  -> { where.not(flagged_inappropriate: true) }
  scope :without_any_reviews,           -> { left_joins(:reviews).where(reviews: {id: nil}) }

end

left_joins(:reviews).where(reviews: {id: nil}) max 對left_joins(:reviews).where(reviews: {id: nil})位的回答。

另外,這一點:

<div id="norev-container">
  <% @bars.each do |bar| %>
    <% if bar.name? && !bar.flagged_innapropriate && bar.reviews.length == 0 %>
      <div class="bar-container">
        <%= link_to image_tag(bar.picture.thumb.url), %`/bars/#{bar.id}/reviews/new`%>
      </div>
    <% end %>
  <% end %>
</div>

……真的很可怕:

  1. 你不應該在視圖中有那么多邏輯,
  2. 你有一個 N+1 問題
  3. 您正在手工制作鏈接!

因此,請嘗試以下操作:

<div id="norev-container">
  <% @bars_needing_review.each do |bar| %>
      <div class="bar-container">
        <%= link_to new_bar_review_path(bar) do %>
          <%= image_tag(bar.picture.thumb.url) %>
        <% end %>
      </div>
  <% end %>
</div>

語法可能有點偏差。 再次,對匆忙感到抱歉。 你仍然會遇到那個bar.picture調用的 N+1 問題 b/c。 因此,您可能需要執行以下操作:

@bars_needing_review = Bar.includes(:picture).with_name.not_flagged_as_inappropriate.without_any_reviews

此外,您需要設置routes.rb以包含以下內容:

resources :bars do 
  resources :reviews, shallow: true
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM