2016-10-05 3 views
0

Я попытался задать этот вопрос ранее, и все прошло неплохо - надеюсь, на этот раз я сделаю это лучше.Ruby On Rails - Скрытие JOIN с использованием HAVING для области

У меня есть три модели

class Flavor < ActiveRecord::Base 
    has_many :components 
    has_many :ingredients, through: :components 
end 

class Ingredient < ActiveRecord::Base 
    has_many :components 
    has_many :flavors, through: :components 
end 

class Component < ActiveRecord::Base 
    belongs_to :ingredient 
    belongs_to :flavor 

    validates :percentage, presence: true 
end 

Порция сделана из ароматов, но аромат может быть сделана только в партию, если это компонента добавить до 100 процентов (отсюда, почему я поставил процент проверки там так он был представлен).

Сначала я попытался написать это как сферу, но никогда не мог заставить его работать, модель тестирования я создал работал с использованием

def self.batch_eligible 
    self.find_by_sql("Select flavors.* FROM flavors 
    INNER JOIN components on flavors.id = components.flavor_id 
    GROUP BY flavors.id, flavors.name 
    HAVING SUM(percentage)=100") 
end 

я сделал попытку рамки и не удалось. Вот окончательный вариант рамки я придумал:

scope :batch_eligible, -> {joins(:components).having('SUM(percentage) = 100').group('flavor.id')}

Полученный объект будет использоваться для заполнения списка выбора в форме для партий (ароматизаторы могут существовать до того, как компоненты полностью разработаны) ,

Я полагаю, что ограничение здесь - мое понимание областей - так, как бы область была построена правильно, чтобы произвести те же результаты, что и выражение find_by_sql?

Вся помощь приветствуется, спасибо.

В ответ на первый комментарий - я попробовал множество областей без захвата ошибок - объем выше возвращает эту ошибку:

ActiveRecord::StatementInvalid: 
    PG::UndefinedTable: ERROR: missing FROM-clause entry for table "flavor" 
    LINE 1: SELECT COUNT(*) AS count_all, flavor.id AS flavor_id FROM "f... 
             ^
    : SELECT COUNT(*) AS count_all, flavor.id AS flavor_id FROM "flavors" INNER JOIN "components" ON "components"."flavor_id" = "flavors"."id" GROUP BY flavor.id HAVING SUM(percentage) = 100 

меняющейся его вкусы идентификатор делает его «работа», но это Безразлично» t вернет правильную информацию.

еще один кусок кода - модели тестирования

require 'rails_helper' 

RSpec.describe Flavor, type: :model do 
    let!(:flavor) {FactoryGirl.create(:flavor)} 
    let!(:flavor2) {FactoryGirl.create(:flavor)} 
    let!(:ingredient) {FactoryGirl.create(:ingredient)} 
    let!(:component) {FactoryGirl.create(:component, flavor: flavor, ingredient: ingredient, percentage: 25)} 
    let!(:component1) {FactoryGirl.create(:component, flavor: flavor2, ingredient: ingredient, percentage: 100)} 

    it "should have a default archive as false" do 
    expect(flavor.archive).to be(false) 
    end 

    it "should only have valid flavors for batch creation" do 
    expect(Flavor.batch_eligible.count).to eq 1 
    expect(Flavor.batcH_eligible.first).to eq flavor2 
    end 
end 

Даже с чистой базой данных испытание - batch_eligible отсчет 4 - не один

Еще одно замечание - тесты DO проходят с find_by_sql функции - Я просто считаю, что область должна быть возможной?

+1

Какие ошибки вы наблюдали, когда вы пробовали версию, которую вы имеете до сих пор?Вы пытались удалить части и посмотреть, что результат, чтобы убедиться, что части работают независимо? или какая часть - это кусок, который ломается? –

+1

@TarynEast Пожалуйста, см. Выше править - относительно ошибки - как я попытался исправить это в ответ на ошибку и все еще не работает. Я действительно думал, что это будет легко сделать – MageeWorld

+1

ok, так что re: жалуясь на flavour_id вещь ... вам может потребоваться быть явным о том, к каким столбцам относятся, например, возможно, попробуйте 'joins (: components) .references (: components) .having ('SUM (components.percentage) = 100'). group ('components.flavor_id') 'Также я бы рекомендовал не начинать с' count' -> иногда сложный объем работы, но рельсы не могут преобразовать его в правильный запрос «count» ... начать с того, что он возвращает '.all', а затем делает' .size' на этом (просто чтобы получить его отчасти) ... затем выясните, как заставить 'count' работать правильно , –

ответ

1

Подходит для @taryneast для помощи - я был направлен в правильном направлении.

После исправления вопроса об объеме с помощью flavors.id - я выполнил проверку, чтобы посмотреть, что происходит, но я также выполнял различные функции.

puts Flavor.batch_eligible.count или puts Flavor.batch_eligible.size обе дают то же самое, например, хеш {312 => 1} - 312 будет идентификатором фабрично-заводского вкуса.

Таким образом, проблема (как только я решил, flavors.id) не был в области - это было в тесте. Вам нужно проверить LENGTH, Flavor.batch_eligible.length дает целое число 1, которое я хотел.

Возможно, все остальные знали это - я этого не делал.

Спасибо Taryn

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