繁体   English   中英

将不同表中的数据提取到单个视图中

[英]Pulling data from different tables into a single view

我最近开始学习Ruby on Rails,现在正在开发我的第一个电子商务Web应用程序。 应用程序数据库目前有两个表: productsvariants

products包含idnamedescription等。每种产品可能有几种变体。

variants包含idproduct_idpriceimage等。它还具有一个布尔字段default_var ,用于确定用户首次看到该产品时应在页面上显示的默认变体。

这些模型如下所示:

class Product < ActiveRecord::Base
  has_many :variants
end

class Variant < ActiveRecord::Base
  belongs_to :product
  scope :default, -> {where(dafault_var: 1)}
end

我希望在索引页面上能够显示产品列表以及旁边的图像,价格和说明,因此信息应该是两个表中值的组合。

在index.erb视图文件中,如果我尝试使用each方法遍历产品数组,则必须使用index变量:

<% @products.each do |product| %>

我想不出一种通过此局部变量访问变体控制器方法的方法。 variants表中获取priceimage等数据的最佳方法是什么? 我想将视图中的Ruby代码保持在最低限度。

控制器当前具有以下代码:

class ProductsController < ApplicationController
  def index
    @products = Product.paginate(:page => params[:page], :per_page => 5)
    #@products = Product.all
  end

...

class VariantsController < ApplicationController
  def index
    @product = Product.find(params[:id])
    @variants = @product.variants
  end
end
  1. 基本上,您可以直接从product获取variants

     <% @products.each do |product| %> <% product.variants.each do |variant| %> ...render your variant... <% end %> <% end %> 
  2. 稍后将导致N + 1查询问题,因为每次您从product获得variants时,都会运行查询。 因此,我们可以在ProductsController@products进行@products加载

     @products = Product.includes(:variants).paginate(:page => params[:page], :per_page => 5) 
  3. @variantsVariantsController中的@variants都没有绑定到ProductsControllerVariantsController的实例变量将用于变量视图。 您处于产品视图中。

因为您有一个包含图片和价格的默认变体,所以我会这样做

class Product < ActiveRecord::Base
  def default_variant
    self.variants.find_by_default_var(1)
  end
end

<% @products.each do |product| %>
  <ul>
    <li><%= product.description %></li>
    <li><%= product.default_variant.price %></li>
    <li><%= image_tag(product.default_variant.image) %></li>
  </ul>
<% end %>

ActiveRecord访问variants是使用:

#app/views/products/index.html.erb
<% @products.each do |product| %>
   <% @product.variants.each do |variant| %>
      <%= variant.name %>
   <% end %>
<% end %>

由于您使用的是has_many ,因此可以将default变体指定为关联,甚至可以使用ActiveRecord关联扩展

#app/models/product.rb
class Product < ActiveRecord::Base
   has_many :variants do
      def default 
        find_by default_var: true #-> @product.variants.default
      end
   end
   has_one  :default_variant, -> { find_by(default_var: true) }, class_name: "Variant", foreign_key: :product_id #-> @product.default_variant
end

这将允许您调用:

#app/views/products/index.html.erb
<% @products.each do |product| %>
   <%= product.default_variant.name %>
<% end %>

-

我不知道这会对n+1等产生什么影响

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM