2016-01-31 3 views
0

Недавно я начал изучать Ruby on Rails, и сейчас я занимаюсь разработкой своего первого веб-приложения для электронной коммерции. База данных приложение имеет две таблицы в данный момент: products и variantsВытягивание данных из разных таблиц в один вид

products содержит id, name, description и т.д. Каждый продукт может иметь несколько вариантов.

variants содержит id, product_id, price, image и т.д. Он также имеет логическое поле 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 я использовать индексную переменную:

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

Я не могу придумать способ доступ к методам контроллера вариантов через эту локальную переменную. Каков наилучший способ получить данные, такие как price и image из таблицы variants? Я хотел бы сохранить минимальный код 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 
+0

Variant методы? можете ли вы объяснить или показать их? – Haider

+0

Также вы хотите отобразить все варианты продукта? – Haider

+0

Я предполагаю, что я использовал термин методы неправильно. Насколько я понимаю, вся логика программы должна идти в контроллер, поэтому я действительно хотел спросить: есть ли способ избежать непосредственного запроса базы данных в представлении и, скорее, ее приятно разделить на контроллер. Например, на данный момент, чтобы получить доступ к полям таблицы вариантов, у меня есть эта строка в моем файле вида: '<% variant = Variant.find_by (product_id: product.id, default_var: 1)%>' Мне нужен только доступ вариант по умолчанию на индексной странице. – Aliona

ответ

0

Потому что у вас есть один вариант по умолчанию, который имеет изображение и цену, я хотел бы сделать что-то вроде этого

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 %> 
0
  1. В принципе, вы можете получить, что variants от product непосредственно

    <% @products.each do |product| %> 
        <% product.variants.each do |variant| %> 
        ...render your variant... 
        <% end %>  
    <% end %> 
    
  2. Это вызовет проблемы запроса N + 1 позже, так как каждый раз, когда вы получаете variants от product, запрос будет запущен. Таким образом, мы можем сделать нетерпеливые нагрузки для @products в ProductsController

    @products = Product.includes(:variants).paginate(:page => params[:page], :per_page => 5) 
    
  3. @variants в VariantsController не является обязательными для ProductsController во всяком случае, переменный экземпляр в VariantsController будет использоваться для представлений варианта. Вы находитесь в представлении продукта.

0

В ActiveRecord способ доступа к variants заключается в использовании:

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

Поскольку вы используете has_many, вы можете указать вариант default как ассоциацию, или e вэн использовать ActiveRecord Association Extension:

#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 и т.д. контроллер

Смежные вопросы