
Eugene
28.07.2018
11:10:42
А, увы


Nico
28.07.2018
11:33:08
Всем кофе в этом чате!
Помогите разобраться плз.
Есть 3 модели: search, item, price и сервис, который создает или обновляет items и создает prices. За пределами тестов все норм и работает как надо.
Но простая спека не хочет работать, причем как-то странно. При запуске rspec ./mysterious_spec.rb тест проходит, а если все спеки запускаю, то не проходит
Кто-то с подобным сталкивался? Куда копать?
Текст спеки:
it 'update old items and create prices' do
expect(items_data).to be
expect(old_item).to be_valid
expect do
described_class.call(search_id: search.id,
data: items_data)
end.to change { Item.first.updated_at }
.and change { Price.count }.by(1)
end
первые два expect проходят, т.е. old_item созданный factory_bot виден,
а когда я через дебаггер оказываюсь внутри described_class, то Item.count = 0
и сервис не увидев старый item, создает новый, а спека выдает
expected `Item.first.updated_at` to have changed, but is still 2018-07-28 11:26:56.262143000 +0000
wtf?


Иван
28.07.2018
11:49:10
Всем кофе в этом чате!
Помогите разобраться плз.
Есть 3 модели: search, item, price и сервис, который создает или обновляет items и создает prices. За пределами тестов все норм и работает как надо.
Но простая спека не хочет работать, причем как-то странно. При запуске rspec ./mysterious_spec.rb тест проходит, а если все спеки запускаю, то не проходит
Кто-то с подобным сталкивался? Куда копать?
Текст спеки:
it 'update old items and create prices' do
expect(items_data).to be
expect(old_item).to be_valid
expect do
described_class.call(search_id: search.id,
data: items_data)
end.to change { Item.first.updated_at }
.and change { Price.count }.by(1)
end
первые два expect проходят, т.е. old_item созданный factory_bot виден,
а когда я через дебаггер оказываюсь внутри described_class, то Item.count = 0
и сервис не увидев старый item, создает новый, а спека выдает
expected `Item.first.updated_at` to have changed, but is still 2018-07-28 11:26:56.262143000 +0000
wtf?
этот old_item точно через FactoryBot.create создается? может он просто билдится и не записывается в бд?


Nico
28.07.2018
11:49:26
let(:old_item) { create(:item, search: search) }

Google

Vasiliy
28.07.2018
11:50:50
У тебя он лениво создаётся

Иван
28.07.2018
11:51:29
то есть если binding.pry поставить между 2 и 3 expect то там будет Item.coun == 1 а внутритовего сервиса 0?

Vasiliy
28.07.2018
11:51:47
Я хз как у тебя там логика устроена, но попробуй let!

Nico
28.07.2018
11:52:16
он не во всех спеках нужен, дергается непосредственно вначале блока it
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, js: true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end

Vasiliy
28.07.2018
11:52:30
Или вызов сделай old_item в дебагере перед тем как юзать

Nico
28.07.2018
11:52:41
при таких настройках перед каждым it база обнуляется?

Vasiliy
28.07.2018
11:53:08
Датабейс клинер тут не причем по мойму


Иван
28.07.2018
11:53:18
Всем кофе в этом чате!
Помогите разобраться плз.
Есть 3 модели: search, item, price и сервис, который создает или обновляет items и создает prices. За пределами тестов все норм и работает как надо.
Но простая спека не хочет работать, причем как-то странно. При запуске rspec ./mysterious_spec.rb тест проходит, а если все спеки запускаю, то не проходит
Кто-то с подобным сталкивался? Куда копать?
Текст спеки:
it 'update old items and create prices' do
expect(items_data).to be
expect(old_item).to be_valid
expect do
described_class.call(search_id: search.id,
data: items_data)
end.to change { Item.first.updated_at }
.and change { Price.count }.by(1)
end
первые два expect проходят, т.е. old_item созданный factory_bot виден,
а когда я через дебаггер оказываюсь внутри described_class, то Item.count = 0
и сервис не увидев старый item, создает новый, а спека выдает
expected `Item.first.updated_at` to have changed, but is still 2018-07-28 11:26:56.262143000 +0000
wtf?
если ты говоришь что отдельно этот спек проходит а вместе с остальными спеками падает то восползуйся bisect
он тебе найдет минимальный набор тестов при которых происходит падение


Nico
28.07.2018
12:08:52
Нашел где проблема, добавил к спеку
expect(old_item.product_id).to eq(items_data.keys.first)
Получил
Failure/Error: expect(old_item.product_id).to eq(items_data.keys.first)
expected: "product_1"
got: "product_2"
код фабрики:
factory :item do
sequence(:title) { |n| "title_#{n}" }
sequence(:product_id) { |n| "product_#{n}" }
url 'url'
search
end
Что за магия? Почему factory_bot выдает product_2?
И как после того, как был создан old_item, может быть такое, что оказываясь внутри сервиса, Item.count = 0

Google

Иван
28.07.2018
12:26:18
Если тебе важно соответствие product_id то я бы не стал доверять это sequence

Nico
28.07.2018
12:27:56
явсепонял, как часто и бывает, идиотская ошибка.
фабрика создает объект с id=2, видимо надо получше разобраться с db cleaner
А Item.count = 0 внутри сервиса получилось из-за того, что у меня в спеке 2 раза дергается сервис, и в первом случае действительно Item.count должно быть равно нулю. Там я потерянный old_item и искал
Почувствуй себя дебилом, называется :D

Nikita
29.07.2018
06:37:14
Ловите балтийский берег

Eugene
29.07.2018
09:07:36
Народ
@gambala @nikmelnikov @viis_w @tralalatralala в сидрерии на моховой около 22?
Кто хочет ещё приходите тоже, обзнакомимся

Dimon
29.07.2018
09:09:12
Норм, я подтяну ногу

Eugene
29.07.2018
09:09:30
Я могу немного задержаться, дождитесь уж)

Dimon
29.07.2018
09:10:02
Разберёмся
Я может тоже задержусь
У меня так то связка порвана

Eugene
29.07.2018
09:10:58
Ок

Nikita
29.07.2018
09:30:20

Undefined
29.07.2018
09:47:05
А из Самары есть кто интересно?

Nikita
29.07.2018
10:08:20

Undefined
29.07.2018
10:09:05
Может тоже тогда собраться всееми и на следующей неделе пойти в бар какой-нибудь?

Ilona
29.07.2018
10:23:11

Nikita
29.07.2018
10:27:25
Раз Илона будет, точно приду ?
А есть hr блеклисты?

Google

Nikita
29.07.2018
10:31:29
Иногда в компаниях бывают, но большого общего нет

Nikita
29.07.2018
10:34:22
Началось

Eugene
29.07.2018
11:07:31
Никит
Как перекат?

Nikita
29.07.2018
14:06:41
а то я уже спать хочу)))

Nikita
29.07.2018
14:10:47
Щас в ашан поеду всякую поеботу покупать
Завтра утром в офис почалю

Eugene
29.07.2018
15:50:47
Иди щас поспи)

Nikita
29.07.2018
16:02:56
В кино разве что

Nico
29.07.2018
16:58:50
Подскажите пожалуйста, как сюда сортировку по price_date добавить?
# Return all items for search with actual item.price
scope :with_actual_price, (
lambda do |search_id|
where(search_id: search_id)
.select('DISTINCT ON (items.product_id) items.id,
items.product_id,
items.source,
items.title,
items.url,
prices.value AS price,
prices.created_at AS price_date')
.joins(:prices)
.having('prices.created_at = max(prices.created_at)')
.group('items.id,
items.product_id,
items.source,
items.title,
items.url,
price,
price_date')
end
)

I
29.07.2018
17:21:51
э
а order(prices.created_at) не помогает?

Иван
29.07.2018
17:25:07
кстати наличие distinct on и отсутвие order by намекает что он тебе не очень то и нужен

Eugene
29.07.2018
18:45:43
Мы в пути
Кто прибудет первым, пишите куда сели

Nikita
29.07.2018
18:47:06

Dimon
29.07.2018
18:55:16
скоре буду, паци

Nikita
29.07.2018
19:05:28
Опаздываю

Google

Nikita
29.07.2018
19:05:43
Eta 22:40

Eugene
29.07.2018
19:06:42
Ок
Примерно так же
Сук я двух Никит сегодня спутал по телефону
Это провал

Nikita
29.07.2018
19:07:43

Eugene
29.07.2018
19:09:35
Da
Ну номер незнакомый
Никита

Admin
ERROR: S client not available

Eugene
29.07.2018
19:10:16
Я не заподозрил подвоха
А по голосу в диком шуме было анрил узнать

Dimon
29.07.2018
19:19:04
Я барную стойку уже подпираю

Eugene
29.07.2018
19:24:56
В 15 минутах

Nikita
29.07.2018
19:29:36
Я тут
Если вы стол не бронили, то в дальнем зале вот

Eugene
29.07.2018
19:55:01
Илону ждем

Roman
29.07.2018
20:24:49
а че димасик бороду сбрил

Google

Eugene
29.07.2018
20:26:09
И кепку отрастил

Anton
29.07.2018
20:26:10
Весело у вас!

Ivan
29.07.2018
20:42:20
Эх душевно

Dimon
29.07.2018
21:04:05


Nico
29.07.2018
21:40:18
э
а order(prices.created_at) не помогает?
фак ркн, только сейчас заметил, что телега отвалилась(
если добавить .order('prices.created_at'), то всплывает
SELECT DISTINCT ON expressions must match initial ORDER BY expressions
я решил пока через order_by(&:price_date), но понимаю, что можно красивее
кстати наличие distinct on и отсутвие order by намекает что он тебе не очень то и нужен
запрос с DISTINCT
reload!;Item.with_actual_price(1).to_a.size => 29
без
reload!;Item.with_actual_price(1).to_a.size => 31
это запрос для получения списка items с актуальными ценами(последнаяя созданная цена для item)
схема простая совсем, если что
create_table "items", force: :cascade do |t|
t.integer "search_id", null: false
t.string "title"
t.string "url"
t.string "product_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "source"
t.index ["product_id"], name: "index_items_on_product_id", unique: true
end
create_table "prices", force: :cascade do |t|
t.integer "item_id", null: false
t.integer "value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["item_id"], name: "index_prices_on_item_id"
end


Иван
29.07.2018
21:47:57
запрос с DISTINCT
reload!;Item.with_actual_price(1).to_a.size => 29
без
reload!;Item.with_actual_price(1).to_a.size => 31
это запрос для получения списка items с актуальными ценами(последнаяя созданная цена для item)
схема простая совсем, если что
create_table "items", force: :cascade do |t|
t.integer "search_id", null: false
t.string "title"
t.string "url"
t.string "product_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "source"
t.index ["product_id"], name: "index_items_on_product_id", unique: true
end
create_table "prices", force: :cascade do |t|
t.integer "item_id", null: false
t.integer "value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["item_id"], name: "index_prices_on_item_id"
end
я к тому что там скорее всего обычный distinct можно заюзать, а не distinct on

Nico
29.07.2018
21:48:27

Иван
29.07.2018
21:51:00

Nico
29.07.2018
21:52:15

Иван
29.07.2018
21:57:39

Nico
29.07.2018
21:58:02
кажется в синтаксисе ошибка
(PG::SyntaxError: ERROR: syntax error at or near "."
LINE 2: items.id,
что-то не так?
scope :with_actual_price, (
lambda do |search_id|
where(search_id: search_id)
.select('DISTINCT (items.product_id)
items.id,
items.product_id,
items.source,
items.title,
items.url,
prices.value AS price,
prices.created_at AS price_date')
.joins(:prices)
.having('prices.created_at = max(prices.created_at)')
.group('items.id,
items.product_id,
items.source,
items.title,
items.url,
price,
price_date')
.order('prices.created_at')
end
)
запятая после distinct
в итоге неверно работает, не фильтрует дублирующиеся items.product_id


Иван
29.07.2018
22:20:43
хм а если сделать distinct on (items.product_id) и добавть order("items.product_id, prices.created_at desc")
и убрать having с group
вообще
как то так -
scope :with_actual_price, (
lambda do |search_id|
where(search_id: search_id)
.select('DISTINCT ON (items.product_id)
items.id,
items.product_id,
items.source,
items.title,
items.url,
prices.value AS price,
prices.created_at AS price_date')
.joins(:prices)
.order('items.product_id, prices.created_at DESC')
end
)
так по идее у тебя к каждому product_id должна применится последняя цена