how to each_cons in batches with active record - ruby-on-rails

The following throws a LocalJumpError
records.find_each.each_cons(3)
Is there a built-in way to use each_cons in memory-friendly batches?
Edit:
Ideally the overlap would work across the batch limit. each_cons interates over overlapping groups, so records with ids (0, 1, 2), (1, 2, 3), (2, 3, 4) etc.
If the batch size is 1000 (which I think it is for Rails), it would be less than optimal to have the overlap limited within the batch group. For example the records with indexes (997, 998, 999) then next iteration to (1000, 1001, 1002) is undesirable.

Here's a custom method to accomplish it:
def batched_each_cons(batch_size:, each_cons:, model:)
end_of_previous = []
model.find_in_batches(batch_size: batch_size) do |batch|
rebuilt_batch = end_of_previous + batch
end_of_previous = batch[(-(each_cons-1))..-1]
rebuilt_batch.each_cons(each_cons) do |cons|
yield cons
end
end
end
batched_each_cons(batch_size: 5, each_cons: 3, model: User) do | users |
# puts users.map(&:name)
puts users.map(&:id).inspect
end
This gives:
User Load (0.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 5]]
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" > $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 5], ["LIMIT", 5]]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 10]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" > $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 10], ["LIMIT", 5]]
[9, 10, 11]
[10, 11, 12]
[11, 12, 13]
[12, 13, 14]
[13, 14, 15]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" > $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 15], ["LIMIT", 5]]
[14, 15, 16]
[15, 16, 17]
[16, 17, 18]
[17, 18, 19]
[18, 19, 20]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" > $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 20], ["LIMIT", 5]]
(This is in my local console, normally you would not see 'User Load...', that is there to show the batching is working)

yeah, like this:
User.all.find_in_batches do |group|
group.each_cons(3) { |users| puts users.map(&:name) }
end

Related

Strange Rails ActiveRecord Behavior

Can someone please explain why the following queries return diff results?
If I run a simple "last" query I get an object back.
>> j = Job.last
(1.6ms) SELECT sqlite_version(*)
Job Load (0.7ms) SELECT "jobs".* FROM "jobs" ORDER BY "jobs"."id" DESC LIMIT ? [["LIMIT", 1]]
=> #<Job id: 12, customer_id: 3, description: nil, shoot_start_date: "2020-11-25
00:00:00", shoot_end_date: "2020-11-26 00:00:00", submission_deadline: "2020-11-27
00:00:00", delivery_deadline: "2020-11-28 00:00:00", created_at: "2020-11-25 21:44:22",
updated_at: "2020-12-14 19:30:06", token: "fd2356c1-996b-4f95-b24a-8c92829af1fe", name:
"teesting">
And with this object I can get children as follows:
>> j.job_entries
JobEntry Load (0.7ms) SELECT "job_entries".* FROM "job_entries" WHERE
"job_entries"."job_id" = ? LIMIT ? [["job_id", 12], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<JobEntry id: 8, entity_id: 12,
agency_id: 35, created_at: "2020-12-07 21:27:47", updated_at: "2020-12-07 21:27:47", job_id:
12, job_role_id: 8>, #<JobEntry id: 9, entity_id: 13, agency_id: 35, created_at: "2020-12-14
17:35:30", updated_at: "2020-12-14 17:35:30", job_id: 12, job_role_id: 7>]>
HOWEVER, when I run a method on my object which is the following code:
def self.getJobAndSubmissions(token)
Job.includes(job_entries: :images_attachments).where(:token => token)
end
I get the very same record with attachments:
>> j = Job.getJobAndSubmissions('fd2356c1-996b-4f95-b24a-8c92829af1fe')
Job Load (0.9ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."token" = ? LIMIT ? [["token",
"fd2356c1-996b-4f95-b24a-8c92829af1fe"], ["LIMIT", 11]]
JobEntry Load (0.2ms) SELECT "job_entries".* FROM "job_entries" WHERE
"job_entries"."job_id" = ? [["job_id", 12]]
ActiveStorage::Attachment Load (1.0ms) SELECT "active_storage_attachments".* FROM
"active_storage_attachments" WHERE "active_storage_attachments"."record_type" = ? AND
"active_storage_attachments"."name" = ? AND "active_storage_attachments"."record_id" IN (?,
?) [["record_type", "JobEntry"], ["name", "images"], ["record_id", 8], ["record_id", 9]]
=> #<ActiveRecord::Relation [#<Job id: 12, customer_id: 3, description: nil,
shoot_start_date: "2020-11-25 00:00:00", shoot_end_date: "2020-11-26 00:00:00",
submission_deadline: "2020-11-27 00:00:00", delivery_deadline: "2020-11-28 00:00:00",
created_at: "2020-11-25 21:44:22", updated_at: "2020-12-14 19:30:06", token: "fd2356c1-996b-
4f95-b24a-8c92829af1fe", name: "teesting">]>
But suddenly, child references no longer work.
>> j.job_entries
Traceback (most recent call last):
1: from (irb):4
Job Load (0.2ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."token" = ? LIMIT ? [["token",
"fd2356c1-996b-4f95-b24a-8c92829af1fe"], ["LIMIT", 11]]
JobEntry Load (0.1ms) SELECT "job_entries".* FROM "job_entries" WHERE
"job_entries"."job_id" = ? [["job_id", 12]]
ActiveStorage::Attachment Load (0.2ms) SELECT "active_storage_attachments".* FROM
"active_storage_attachments" WHERE "active_storage_attachments"."record_type" = ? AND
"active_storage_attachments"."name" = ? AND "active_storage_attachments"."record_id" IN (?,
?) [["record_type", "JobEntry"], ["name", "images"], ["record_id", 8], ["record_id", 9]]
NoMethodError (undefined method `job_entries' for #.
<Job::ActiveRecord_Relation:0x00005562db1258c0>)
Did you mean? entries
What the? Please help me understand why this is happening!
Job.last
will return an ActiveRecord object.
Job.includes(job_entries: :images_attachments).where(:token => token)
returns an ActiveRecord::Relation which means you can't call job_entries on it.
You can get an object with this code
# These do the same thing
Job.find_by_token(token)
Job.find_by(token: token)
NoMethodError (undefined method `job_entries' for #. <Job::ActiveRecord_Relation:0x00005562db1258c0>)
Note the error message is not for Job but for a Job::ActiveRecord_Relation.
#last returns a single Job. #where returns a set of Jobs stored in an ActiveRecord::Relation. Job::ActiveRecord_Relation is a relation specific to Job.
You can also see this in the returned value...
>> j = Job.getJobAndSubmissions('fd2356c1-996b-4f95-b24a-8c92829af1fe')
...
=> #<ActiveRecord::Relation [#<Job id: 12, ...]>

How to avoid N+1 queries in scope with parameter in Rails

I met a N+1 issue in this situation:
Library has many Programs. Now I want to get all the programs located a certain country, so I have a code:
country = "US"
programs = #libraries.includes(:programs).map do |library|
library.programs.where(country: country)
end
But now there is N+1 problem:
Program Load (0.8ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 15], ["country", "US"]]
Program Load (0.4ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 73], ["country", "US"]]
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 27], ["country", "US"]]
Program Load (0.3ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 177], ["country", "US"]]
Program Load (0.3ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 38], ["country", "US"]]
Program Load (0.4ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 51], ["country", "US"]]
Program Load (0.6ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 18], ["country", "US"]]
Program Load (0.3ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 20], ["country", "US"]]
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 42], ["country", "US"]]
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."library_id" = $1 AND "programs"."country" = $2 [["library_id", 39], ["country", "US"]]
Update:
My purpose is not to just filter the programs, but to use it. For example:
programs = #libraries.includes(:programs).each do |library|
if library.programs.where(country: country).size < 5
puts "US programs are less than 5 so you can still add"
end
end
Does anyone know how to solve the N+1 problem?
You can chain the where query to the includes like below
programs = #libraries.includes(:programs).where(programs: {country: country})
which should solve the N+1 problem.
See specifying-conditions-on-eager-loaded-associations
Update #1:
You can simply do it like this
programs = #libraries.includes(:programs).where(programs: {country: country}).size < 5 #returns true or false
if programs #true
puts "US programs are less than 5 so you can still add"
else #false
#your code
end
Update #2:
This should do
programs_size = #libraries.includes(:programs).where(programs: {country: country}).map { |library| library.programs.size }
Which would perform only one query and returns the size of each library.programs matching that condition as array something like below
=> [5, 4, 7, 4, 6, 2, 1]
Now you can iterate over the programs_size array and perform the logic
programs_size.each do |ps|
if ps < 5 #true
puts "US programs are less than 5 so you can still add"
else #false
#your code
end
end

Eager loading with scope in Rails

I found many questions with similar title but none of them could solve my question.
I have a model Program which has many Videos:
class Program < ActiveRecord::Base
has_many :videos
...
end
Then I have scope in Video:
class Video < ActiveRecord::Base
belongs_to :program
scope :trailer, -> { where(video_type: 0) }
...
end
Firstly, when I have a list of programs and want to access videos, I have no N+1 program with include method:
> #programs.includes(:videos).map { |p| p.videos.size }
Program Load (0.6ms) SELECT "programs".* FROM "programs" ORDER BY "programs"."id" ASC LIMIT 10
Video Load (0.5ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" IN (8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
However, when I try to get the scope, it will touch Database again:
> #programs.includes(:videos).map { |p| p.videos.trailer }
Program Load (0.6ms) SELECT "programs".* FROM "programs" ORDER BY "programs"."id" ASC LIMIT 10
Video Load (0.5ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" IN (8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
Video Load (0.4ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 8], ["video_type", 0]]
Video Load (0.4ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 9], ["video_type", 0]]
Video Load (12.4ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 10], ["video_type", 0]]
Video Load (0.3ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 11], ["video_type", 0]]
Video Load (0.3ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 12], ["video_type", 0]]
Video Load (0.3ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 13], ["video_type", 0]]
Video Load (0.3ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 14], ["video_type", 0]]
Video Load (0.3ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 15], ["video_type", 0]]
Video Load (0.4ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 16], ["video_type", 0]]
Video Load (0.4ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" = $1 AND "videos"."video_type" = $2 ORDER BY "videos"."id" ASC LIMIT 1 [["program_id", 17], ["video_type", 0]]
You can see it will load DB many times which lead to a bad performance.
#<Benchmark::Tms:0x007f95faa8fab0 #label="", #real=0.02663199999369681, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.019999999999999574, #total=0.019999999999999574>
One solution I can think of is to convert videos to array and search the array:
> #programs.includes(:videos).map { |program| program.videos.to_ary.select { |v| v.video_type == 0 } }
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."id" IN (8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
Video Load (0.4ms) SELECT "videos".* FROM "videos" WHERE "videos"."program_id" IN (17, 16, 13, 12, 11, 9, 8, 15, 14, 10)
The performance is better but the code is complex.
#<Benchmark::Tms:0x007f95faac8720 #label="", #real=0.006901999993715435, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.010000000000000675, #total=0.010000000000000675>
Another solution I can think of, is to add a new has_many in Program for scope:
class Program < ActiveRecord::Base
has_many :videos
has_many :trailer_videos, -> { where(video_type: 0) }, class: 'Video'
...
end
Then if I includes and call the new relation directly, it will eager load as well.
> #programs.includes(:trailer_videos).map { |program| program.trailer_videos }
Program Load (0.5ms) SELECT "programs".* FROM "programs" WHERE "programs"."id" IN (8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
Video Load (0.3ms) SELECT "videos".* FROM "videos" WHERE "videos"."video_type" = $1 AND "videos"."program_id" IN (17, 16, 13, 12, 11, 9, 8, 15, 14, 10) [["video_type", 0]]
The benchmark is below, which is super fast:
#<Benchmark::Tms:0x007f95fdea96c0 #label="", #real=0.004801000002771616, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.009999999999999787, #total=0.009999999999999787>
However, in this way, it will make the Program model so heavy. Because for each scope in Video, I need to added a related association in Program.
Therefore, I am looking for a better solution, which will keep the scope logic inside of Video, but without N+1 problem.
Cheers
As I said, IMO your approach of adding the has_many :trailer_videos, -> { where(video_type: 0) }, class: 'Video' is the simple and best way to counter your problem. I don't see any drawback in adding more such associations to the model.
In Rails Associations have an optional scope parameter that accepts a lambda that is applied to the Relation (see https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Scopes)
So you could write your models as:
# app/models/video.rb
class Video < ActiveRecord::Base
belongs_to :program
scope :trailer, -> { where(video_type: 0) }
...
end
# app/models/program.rb
class Program < ActiveRecord::Base
has_many :videos
has_many :trailer_videos, -> { trailer }, class: 'Video'
...
end
This way you could keep the definition of the scope in Video and reuse it from Program.
A solution is to use merge with eager_load:
#programs.eager_load(:videos).merge(Video.trailer).map { |p| p.videos.size }
It produces only one query.
If the video types are known to the programmer you can use an ActiveRecord::Enum and some simple metaprogrammng to create assocations programatically for each possible value in the enum.
class Video < ActiveRecord::Base
enum video_type: [:trailer, :promo, :foo, :bar]
end
class Program < ActiveRecord::Base
# this creates trailer_videos etc assocations
Video.video_types.each do |key, int|
# eval is needed since we need to dynamically create
# the lamba for each type
has_many "#{key}_videos".to_sym, eval "->{ Video.send(#{key}) }"
end
end

Why is my code generating an extra query?

I have the following code in my controller :
#unanswered_questions = Question.unanswered_with_tag(params[:tag_id]).paginate(per_page: 10, page: params[:page])
Which calls this method in my Question model:
def self.unanswered_with_tag id
joins(:taggings).where(taggings: { tag_id: id }).where(questions: { num_answers: 0})
end
I expect one sql query that fetches the first 10 unanswered questions on that page, but my logs are showing 2 queries:
Question Load (0.4ms) SELECT "questions".* FROM "questions"
INNER JOIN "taggings" ON "taggings"."question_id" = "questions"."id"
WHERE "taggings"."tag_id" = $1 AND "questions"."num_answers" = $2
ORDER BY "questions"."id" ASC LIMIT $3 OFFSET $4
[["tag_id", 3], ["num_answers", 0], ["LIMIT", 1], ["OFFSET", 0]]
^^Note the LIMIT 1 part.
And the second query :
SELECT "questions".* FROM "questions" INNER JOIN "taggings"
ON "taggings"."question_id" = "questions"."id"
WHERE "taggings"."tag_id" = $1 AND "questions"."num_answers" = $2
LIMIT $3 OFFSET $4
[["tag_id", 3], ["num_answers", 0], ["LIMIT", 10], ["OFFSET", 0]]
Which has LIMIT 10.
Why is this behaviour?
Are you running code in your view that checks whether #unanswered_questions has any rows at all (#exists? for example) to either display the values or not?

spree_i18n product filter

I'm having an issue with the spree_I18n gem and the Spree admin panel.
i'm trying to get the admin product filter to work on spree 3.0 stable.
I found this thread : https://github.com/spree-contrib/spree_i18n/pull/602
I changed my gemfile accordingly
This is my gemfile :
gem 'spree', github: 'spree/spree', branch: '3-0-stable'
gem 'spree_gateway', github: 'spree/spree_gateway', branch: '3-0-stable'
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '3-0-stable'
gem 'spree_i18n', git: 'https://github.com/mvz/spree_i18n.git', branch: '3-0-ransack-translations'
I ran bundle install and bundle update spree_i18n but The admin product filter is still returning all of the products. Is there a step that I missed ?
here are the logs :
Started GET "/admin/products?utf8=%E2%9C%93&q%5Bname_cont%5D=Mug&q%5Bvariants_including_master_sku_cont%5D=&q%5Bdeleted_at_null%5D=1" for 127.0.0.1 at 2015-08-26 13:56:39 +0200
Processing by Spree::Admin::ProductsController#index as HTML
Parameters: {"utf8"=>"✓", "q"=>{"name_cont"=>"Mug", "variants_including_master_sku_cont"=>"", "deleted_at_null"=>"1"}}
Spree::User Load (0.2ms) SELECT "spree_users".* FROM "spree_users" WHERE "spree_users"."deleted_at" IS NULL AND "spree_users"."id" = $1 ORDER BY "spree_users"."id" ASC LIMIT 1 [["id", 1]]
(0.3ms) SELECT COUNT(*) FROM "spree_roles" INNER JOIN "spree_roles_users" ON "spree_roles"."id" = "spree_roles_users"."role_id" WHERE "spree_roles_users"."user_id" = $1 AND "spree_roles"."name" = $2 [["user_id", 1], ["name", "admin"]]
(0.4ms) SELECT DISTINCT COUNT(DISTINCT "spree_products"."id") FROM "spree_products" WHERE "spree_products"."deleted_at" IS NULL
Rendered /Users/stefan/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_index_table_options.html.erb (118.4ms)
(0.4ms) SELECT COUNT(DISTINCT count_column) FROM (SELECT DISTINCT "spree_products"."id" AS count_column FROM "spree_products" WHERE "spree_products"."deleted_at" IS NULL LIMIT 10 OFFSET 0) subquery_for_count
Spree::Product Load (0.5ms) SELECT DISTINCT "spree_products".* FROM "spree_products" WHERE "spree_products"."deleted_at" IS NULL ORDER BY "spree_products"."name" ASC LIMIT 10 OFFSET 0
Spree::Variant Load (0.2ms) SELECT "spree_variants".* FROM "spree_variants" WHERE "spree_variants"."deleted_at" IS NULL AND "spree_variants"."is_master" = $1 AND "spree_variants"."product_id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ORDER BY "spree_variants".position ASC [["is_master", "f"]]
Spree::Image Load (0.6ms) SELECT "spree_assets".* FROM "spree_assets" WHERE "spree_assets"."type" IN ('Spree::Image') AND "spree_assets"."viewable_type" = 'Spree::Variant' AND "spree_assets"."viewable_id" IN (17, 18, 19, 20, 21, 22, 23, 24, 25, 26) ORDER BY "spree_assets"."position" ASC
Spree::Variant Load (0.2ms) SELECT "spree_variants".* FROM "spree_variants" WHERE "spree_variants"."deleted_at" IS NULL AND "spree_variants"."is_master" = $1 AND "spree_variants"."product_id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) [["is_master", "t"]]
Spree::Image Load (0.4ms) SELECT "spree_assets".* FROM "spree_assets" WHERE "spree_assets"."type" IN ('Spree::Image') AND "spree_assets"."viewable_type" = 'Spree::Variant' AND "spree_assets"."viewable_id" IN (1, 2, 3, 4, 5, 7, 6, 10, 9, 8) ORDER BY "spree_assets"."position" ASC
Spree::Price Load (0.1ms) SELECT "spree_prices".* FROM "spree_prices" WHERE "spree_prices"."deleted_at" IS NULL AND "spree_prices"."currency" = $1 AND "spree_prices"."variant_id" IN (1, 2, 3, 4, 5, 7, 6, 10, 9, 8) [["currency", "USD"]]
Spree::Product::Translation Load (0.1ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 1]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 2]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 3]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 4]]
Spree::Product::Translation Load (0.3ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 5]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 6]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 7]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 8]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 9]]
Spree::Product::Translation Load (0.2ms) SELECT "spree_product_translations".* FROM "spree_product_translations" WHERE "spree_product_translations"."spree_product_id" = $1 [["spree_product_id", 10]]
Rendered /Users/stefan/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_index_table_options.html.erb (122.8ms)
Rendered /Users/stefan/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/products/index.html.erb within spree/layouts/admin (370.4ms)
Deface: 1 overrides found for 'spree/admin/shared/_head'
Deface: 'override' matched 1 times with 'title'
Deface: [WARNING] No :original defined for 'override', you should change its definition to include:
:original => 'b94dd9df96e085d9a869128fa811ee3aaf55fab1'
Deface: 1 overrides found for 'spree/admin/shared/_translations'
Deface: 'translation' matched 1 times with 'script'
Deface: [WARNING] No :original defined for 'translation', you should change its definition to include:
:original => '6d879f5c231ff848b4e1023dc0f8b271f922269b'
Rendered /Users/stefan/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_translations.html.erb (27.2ms)
Rendered /Users/stefan/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_head.html.erb (985.0ms)
Deface: 1 overrides found for 'spree/admin/shared/_header'
Deface: 'auth_admin_login_navigation_bar' matched 1 times with '[data-hook='admin_login_navigation_bar'], #admin_login_navigation_bar[data-hook]'
Deface: [ERROR] The original source for 'auth_admin_login_navigation_bar' has changed, this override should be reviewed to ensure it's still valid.
CACHE (0.0ms) SELECT COUNT(*) FROM "spree_roles" INNER JOIN "spree_roles_users" ON "spree_roles"."id" = "spree_roles_users"."role_id" WHERE "spree_roles_users"."user_id" = $1 AND "spree_roles"."name" = $2 [["user_id", 1], ["name", "admin"]]
Rendered /Users/stefan/.rvm/gems/ruby-2.2.1/bundler/gems/spree_auth_devise-2e8e08759c4d/lib/views/backend/spree/layouts/admin/_login_nav.html.erb (1.2ms)
Rendered /Users/steven/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_header.html.erb (15.4ms)
Rendered /Users/steven/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/sub_menu/_product.html.erb (3.3ms)
Rendered /Users/steven/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/sub_menu/_promotion.html.erb (1.2ms)
Spree::Store Load (0.4ms) SELECT "spree_stores".* FROM "spree_stores" WHERE (url like '%localhost%') ORDER BY "spree_stores"."id" ASC LIMIT 1
Spree::Store Load (0.1ms) SELECT "spree_stores".* FROM "spree_stores" WHERE "spree_stores"."default" = $1 ORDER BY "spree_stores"."id" ASC LIMIT 1 [["default", "t"]]
Spree::Country Load (0.3ms) SELECT "spree_countries".* FROM "spree_countries" WHERE "spree_countries"."id" = $1 LIMIT 1 [["id", 232]]
Rendered /Users/steven/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/sub_menu/_configuration.html.erb (7.8ms)
Rendered /Users/steven/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_main_menu.html.erb (106.2ms)
Rendered /Users/stefan/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_content_header.html.erb (0.2ms)
Rendered /Users/steven/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_alert.html.erb (0.0ms)
Rendered /Users/steven/.rvm/gems/ruby-2.2.1/bundler/gems/spree-a39d06ab644e/backend/app/views/spree/admin/shared/_table_filter.html.erb (0.8ms)
Completed 200 OK in 1711ms (Views: 1697.4ms | ActiveRecord: 6.1ms)

Resources