如何只显示已批准的产品 - 目前显示所有产品

时间:2015-11-02 10:01:01

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4

我有一个产品型号和装备型号。我想在我的Outfit show视图中仅显示已批准的产品。它目前正在展示所有产品。产品和服装由一个叫做outfit_products的中间表加入。 outfit_products表有一个布尔批准的列,默认为false。看一看。

如何在我的视图中仅显示已批准的产品?

Outfit.rb

class Outfit < ActiveRecord::Base
  belongs_to :user
  has_many :outfit_products
  has_many :products, through: :outfit_products
end

outfit_product.rb

class OutfitProduct < ActiveRecord::Base
  belongs_to :outfit
  belongs_to :product
end

product.rb

class Product < ActiveRecord::Base
  belongs_to :user
  belongs_to :category
  has_many :outfit_products
  has_many :outfits, through: :outfit_products
end

装备控制器秀

  def show
    @outfit = Outfit.find(params[:id])
  end

Outfit show view只是展示产品的部分

  <% @outfit.products.each do |product| %>
    <div class="box panel panel-default">
      <div class="square_item_image">
        <%= link_to image_tag(product.image.url(:medium)), product %>
      </div>
      <div class ="panel-body">
        <div class = "itemlistretailer">
          <div class="itemlisttitle">
            <%= product.title %>
            <div class = "itemlistprice">
              $<%= product.price %>
            </div>
          </div>
          <div class="item_info">
            <%= image_tag product.user.avatar(:thumb) %>
            <%= link_to product.user.username, product.user %>
          </div>
        </div>
      </div>
    </div>
  <% end %>

以下是我的架构的一部分。请看装备

  create_table "outfit_products", force: :cascade do |t|
    t.integer  "product_id"
    t.integer  "outfit_id"
    t.boolean  "approved",   default: false
    t.boolean  "boolean",    default: false
    t.datetime "created_at",                 null: false
    t.datetime "updated_at",                 null: false
  end

  add_index "outfit_products", ["outfit_id"], name: "index_outfit_products_on_outfit_id"
  add_index "outfit_products", ["product_id"], name: "index_outfit_products_on_product_id"

  create_table "outfits", force: :cascade do |t|
    t.string   "outfit_image_file_name"
    t.string   "outfit_image_content_type"
    t.integer  "outfit_image_file_size"
    t.datetime "outfit_image_updated_at"
    t.integer  "user_id"
    t.datetime "created_at",                null: false
    t.datetime "updated_at",                null: false
    t.string   "caption"
  end

  add_index "outfits", ["user_id"], name: "index_outfits_on_user_id"

  create_table "products", force: :cascade do |t|
    t.string   "title"
    t.decimal  "price"
    t.text     "description"
    t.datetime "created_at",         null: false
    t.datetime "updated_at",         null: false
    t.integer  "user_id"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.integer  "image_file_size"
    t.datetime "image_updated_at"
    t.integer  "category_id"
  end

  add_index "products", ["user_id", "created_at"], name: "index_products_on_user_id_and_created_at"
  add_index "products", ["user_id"], name: "index_products_on_user_id"

end

使用binding.pry

的额外信息
 => 19:   <% binding.pry %>
    20:   <% @outfit.products.each do |product| %>
    21:     <div class="box panel panel-default">
    22:       <div class="square_item_image">
    23:         <%= link_to image_tag(product.image.url(:medium)), product %>
    24:       </div>

[1] pry(#<#<Class:0x007fb2dc346480>>)> @outfit.products
  Product Load (1.1ms)  SELECT "products".* FROM "products" INNER JOIN "outfit_products" ON "products"."id" = "outfit_products"."product_id" WHERE "outfit_products"."outfit_id" = ?  [["outfit_id", 18]]
=> [#<Product:0x007fb2e2a34250
  id: 32,
  title: "Sparkle Shoes",
  price: #<BigDecimal:7fb2e2a4f8e8,'0.18E3',9(27)>,
  description: "this is test description",
  created_at: Thu, 29 Oct 2015 09:14:50 UTC +00:00,
  updated_at: Thu, 29 Oct 2015 09:14:50 UTC +00:00,
  user_id: 53,
  image_file_name: "womenshoes4.jpg",
  image_content_type: "image/jpeg",
  image_file_size: 86729,
  image_updated_at: Thu, 29 Oct 2015 09:14:49 UTC +00:00,
  category_id: 20>]
[2] pry(#<#<Class:0x007fb2dc346480>>)> @outfit.products[0].outfit_products
  OutfitProduct Load (10.2ms)  SELECT "outfit_products".* FROM "outfit_products" WHERE "outfit_products"."product_id" = ?  [["product_id", 32]]
=> [#<OutfitProduct:0x007fb2e2b267d0 id: 5, product_id: 32, outfit_id: 17, approved: true, boolean: false, created_at: Thu, 29 Oct 2015 11:43:41 UTC +00:00, updated_at: Thu, 29 Oct 2015 11:46:05 UTC +00:00>,
 #<OutfitProduct:0x007fb2e2b26618 id: 7, product_id: 32, outfit_id: 18, approved: true, boolean: false, created_at: Thu, 29 Oct 2015 12:05:20 UTC +00:00, updated_at: Thu, 29 Oct 2015 12:05:20 UTC +00:00>,
 #<OutfitProduct:0x007fb2e2b26410 id: 8, product_id: 32, outfit_id: 21, approved: false, boolean: false, created_at: Thu, 29 Oct 2015 12:09:50 UTC +00:00, updated_at: Thu, 29 Oct 2015 12:09:50 UTC +00:00>]
[3] pry(#<#<Class:0x007fb2dc346480>>)>

2 个答案:

答案 0 :(得分:3)

您可以使用第二个关联,仅包含已批准的产品:

class Outfit < ActiveRecord::Base
  has_many :approved_outfit_products, -> { where(approved: true) },
           class_name: 'OutfitProduct'

  has_many :approved_products, through: :approved_outfit_products,
           class_name: 'Product'
end

然后,在视图中:

<% @outfit.approved_products.each do |product| %>

答案 1 :(得分:1)

您可以使用ActiveRecord Association Extension

#app/models/outfit.rb
class Outfit < ActiveRecord::Base
   has_many :products, through: :outfit_products do
      def approved
         ids = where(approved: true).pluck :product_id
         proxy_association.target.find ids
      end
   end
end

这将允许您致电:

@outfit = Outfit.find x
@outfit.products.approved

或者如果你想避开demeter定律:

#app/models/outfit.rb
class Outfit < ActiveRecord::Base
   alias_attribute :approved, to: :products, prefix: true
end

#-> @outfit.products_approved