This is critical to debug bugs related to subscriptions.
Essentially, `has_and_belongs_to_many` doesn't give us the option for
any other column that the foreign keys themselves:
> A has_and_belongs_to_many association creates a direct many-to-many
> connection with another model, with no intervening model.
Source: https://guides.rubyonrails.org/v3.2/association_basics.html#the-has_and_belongs_to_many-association
Note however, that there's no way to update an order_cycle_schedule,
that I can think of but `updated_at` doesn't do any harm.
Activate paper_trail in order_cycles and schedules and track each others ids
An alternative way of doing this would be to use a gem for paper_trail associations but this way we avoid adding a new dependency to the app
It looks like this was probably changed whilst resolving a merge conflict somewhere. The number doesn't match the last migration file, and it's breaking the ofn-install CI build (as well as migrations on fresh servers).
The following query
```sql
SELECT spree_orders . *
FROM spree_orders
WHERE spree_orders . user_id = ?
AND spree_orders . completed_at IS ?
AND spree_orders . created_by_id = ?
ORDER BY created_at DESC LIMIT ?
```
performs quite badly even though LIMIT is always 1 because:
* ORDER BY requires sorting by a column which is not indexed therefore
a sequential scan is performed.
* Although `completed_at` is indexed, `user_id` and `created_by_id` are
not causing a sequential scan.
To make it worse this query is executed very often in the following
controllers among others also related to checkout:
* CartController#populate
* EnterprisesController#Shop
* LineItemsController#bought
* ShopController#products
* ShopController#order_cycle
In some cases this query alone accounts for 66.8% of the total time
of the endpoint.
Results
See by yourself. We move from 56.643ms to 0.077ms. Pretty neat.
```
openfoodnetwork=> explain analyze SELECT "spree_orders".* FROM "spree_orders" WHERE "spree_orders"."user_id" = 1 AND "spree_orders"."completed_at" IS NULL AND "spree_orders"."created_by_id" = 1 ORDER BY created_at DESC LIMIT 1;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Limit (cost=11753.03..11753.04 rows=1 width=195) (actual time=56.580..56.580 rows=0 loops=1)
-> Sort (cost=11753.03..11753.04 rows=1 width=195) (actual time=56.578..56.578 rows=0 loops=1)
Sort Key: created_at DESC
Sort Method: quicksort Memory: 25kB
-> Seq Scan on spree_orders (cost=0.00..11753.02 rows=1 width=195) (actual time=56.571..56.571 rows=0 loops=1)
Filter: ((completed_at IS NULL) AND (user_id = 1) AND (created_by_id = 1))
Rows Removed by Filter: 256135
Planning time: 0.252 ms
Execution time: 56.643 ms
(9 rows)
openfoodnetwork=> CREATE INDEX ON spree_orders (completed_at, user_id, created_by_id, created_at);
CREATE INDEX
openfoodnetwork=> explain analyze SELECT "spree_orders".* FROM "spree_orders" WHERE "spree_orders"."user_id" = 1 AND "spree_orders"."completed_at" IS NULL AND "spree_orders"."created_by_id" = 1 ORDER BY created_at DESC LIMIT 1;
mit (cost=8.45..8.46 rows=1 width=195) (actual time=0.030..0.030 rows=0 loops=1)
-> Sort (cost=8.45..8.46 rows=1 width=195) (actual time=0.029..0.029 rows=0 loops=1)
Sort Key: created_at DESC
Sort Method: quicksort Memory: 25kB
-> Index Scan using spree_orders_completed_at_user_id_created_by_id_created_at_idx on spree_orders (cost=0.42..8.44 rows=1 width=195) (actual time=0.021..0.021 rows=0 loops=1)
Index Cond: ((completed_at IS NULL) AND (user_id = 1) AND (created_by_id = 1))
Planning time: 0.199 ms
Execution time: 0.077 ms
```
This is required because when the default stock location is created, the backorderable_default column doesnt exist and when this column is created, the initial default is true. This is why we need to force it to false here. This column is the default value for on_demand which must be false.
I feel embarrased that this is the second follow up of my last
migration: https://github.com/openfoodfoundation/openfoodnetwork/pull/3126
The last migration didn't change any database structure, but the schema
still needs the latest migration version. Otherwise it will display
pending migrations when setting up the database.
This commit allows to run `bundle exec rake db:reset` in development
without the following message:
Run `rake db:migrate` to update your database then try again.
You have 1 pending migrations:
20181123012635 AssociateCustomersToUsers
The next pull request with a migration would have solved this problem as
well.
This adds a data migration to fix those cases. It defaults to showing
1 unit of the specified weight. That is, if the user chose Kg, it'll
display 1 as unit.
Note that migration logs the process in a log/migrate.log file separate
from the regular Rails log/production.log file.
When you run the migration you'll see something like:
Fixing variants missing unit_value...
Processing variant 12...
Succesfully fixed variant 12
Done!
This helps auditing the changes applied and debug any possible failure
scenarios. You can delete it once all is ok.
* master: (125 commits)
Fix syntax error in GETTING_STARTED.md
Fix syntax error in README.md
Fix link syntax errors in REAME.md and GETTING_STARTED.md
Style recently merged code
Update gem i18n-js to pick up locale changes
Fix embedded shopfront menu responsiveness
Add communications links to README
Fix script/setup by making it less clever
Change import and reset logic to work with first page
Move options to first page
Fix wrong sort predicates in customer index
Reset reverse when clicking another column to sort
Move logic for toggling by column into SortOptions
Generalize sorting through SortOptions service
Remove unused sorting preferences in ColumnsCtrl
Fix frontend sorting in "Bulk Order Management"
Fix frontend sorting in "Customers" index
Change sorting to be done in ascending order first
Wrap rows in customer index with TBODY tag
Update .rubocop_todo.yml
...