After the correction of a wrong syntax I have a new error and I am not sure where it comes from:
categories were created in the console
Category Load (2.0ms) SELECT "categories".* FROM "categories"
=> #<ActiveRecord::Relation [#<Category id: 1, name: "Ruby", created_at: "2016-09-26 09:03:17", updated_at: "2016-09-26 09:03:17">, #<Category id: 2, name: "Rails4", created_at: "2016-09-26 09:03:25", updated_at: "2016-09-27 14:32:39">, #<Category id: 3, name: "Rails5", created_at: "2016-09-26 09:03:30", updated_at: "2016-09-27 14:35:25">, #<Category id: 4, name: "Heroku", created_at: "2016-09-26 09:03:35", updated_at: "2016-09-27 14:35:47">, #<Category id: 5, name: "AWS-Amazon", created_at: "2016-09-26 09:03:43", updated_at: "2016-09-26 09:03:43">]>
When I select:
"Ruby" I have: malformed format string - %R
"Rails4" I have: malformed format string - %R
"Rails5" I have: malformed format string - %R
"Heroku" I have: malformed format string - %H
"AWS-Amazon" I have: too few arguments
I am trying to filter my categories by name:
category model
class Category < ActiveRecord::Base
has_many :tutos
def self.filter(filter)
if filter
where(["name LIKE '%#{filter}%'"]).order('created_at DESC')
else
all
end
end
end
1st Edit
I've tried different way but I have issues in each:
`where(["name LIKE '%#{filter}%'"]).order('created_at DESC')`
returns the malformed string alert
`where("name LIKE '%#{filter}%'").order(created_at: :desc)`
and
`where("name LIKE ?", "%#{filter}%").order('created_at DESC')`
return all the categories without filtering....
you may want to see the tutos/views/index
.container
.row
h1.text-gray Tutorials
.row.search_banner
.col-xs-3
=form_tag tutos_path, :method => 'get' do
=text_field_tag :search, params[:search], placeholder:"Search by keywords"
=submit_tag "Search", class:'btn btn-xs btn-default btn-search'
.col-xs-3
=form_tag tutos_path, :method => 'get' do
=select_tag :filter, options_for_select(Category.all.map{|c| c.name}, params[:filter])
=submit_tag "Search", class:"btn btn-xs btn-default btn-search"
.col-xs-3
-if user_signed_in?
= link_to "Create a tuto", new_tuto_path, class:"btn btn-success"
br
br
#tutos.transitions-enabled
-#tutos.each do |tuto|
.box.panel-default
= link_to image_tag(image_by_category(tuto.category.try(:name))), tuto_path(tuto)
h3 = link_to tuto.title, tuto_path(tuto), class:"title-link"
h6
| Created by:
span<>
= tuto.user.full_name
br
span.glyphicon.glyphicon-heart
span<>
= tuto.get_upvotes.size
br
br
2nd edit
Rails console log : if I search for "Heroku" Cartegory:
but as my categories belongs to tutos... (Maybe have a look on the website filter are not online yet though but you will see the idea)
Should I do something like this
Tuto.category.where("name LIKE ?", "%#{filter}%").order('created_at DESC')
Started GET "/tutos?utf8=%E2%9C%93&filter=Heroku&commit=Search" for ::1 at 2016-09-28 17:50:41 +0200
Processing by TutosController#index as HTML
Parameters: {"utf8"=>"✓", "filter"=>"Heroku", "commit"=>"Search"}
Category Load (0.3ms) SELECT "categories".* FROM "categories"
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Tuto Load (0.1ms) SELECT "tutos".* FROM "tutos"
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (1)
Category Load (0.1ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" IN (2, 3, 5, 4, 1)
(0.1ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 16], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.1ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 17], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.0ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 18], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.0ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 19], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.0ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 20], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.0ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 21], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.0ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 22], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.0ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 23], ["votable_type", "Tuto"], ["vote_flag", "t"]]
(0.0ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."votable_id" = ? AND "votes"."votable_type" = ? AND "votes"."vote_flag" = ? AND "votes"."vote_scope" IS NULL [["votable_id", 24], ["votable_type", "Tuto"], ["vote_flag", "t"]]
Rendered tutos/index.html.slim within layouts/application (29.0ms)
Rendered layouts/_nav.html.slim (0.4ms)
Completed 200 OK in 104ms (Views: 94.1ms | ActiveRecord: 1.9ms)
3rd Edit
tuto model
class Tuto < ActiveRecord::Base
acts_as_votable
belongs_to :user
belongs_to :category
validates :category_id, presence: true
def self.search(search)
if search
where(["title LIKE ?","%#{search}%"]).order('created_at DESC')
else
all
end
end
end
category model
I've build my category filter like the tuto search
class Category < ActiveRecord::Base
has_many :tutos
def self.filter(filter)
if filter
#where(["name LIKE '%#{filter}%'"]).order('created_at DESC')
#where("name LIKE '%#{filter}%'").order(created_at: :desc)
where("name LIKE ?", "%#{filter}%").order('created_at DESC')
else
all
end
end
end
Checked with the suggested raise 'check'
Feel free to ask for more code if needed, as I am not sure where I am wrong...
Many thanks
regards
I fixed it !
In my controller tutos I did this:
many thanks to fanta who took me on the right way !
def index
#binding.pry
if params[:search].present?
#tutos = Tuto.search(params[:search]).includes(:user, :category)
else
#tutos = Tuto.all.includes(:user, :category)
end
if params[:filter].present?
#tutos = Tuto.joins(:category).where('categories.name LIKE ?', params[:filter])
else
#categories = Category.all
end
end
where("name LIKE ?", "%#{filter}%").order('created_at DESC')
Related
Acts-as-Taggable-on is failing to correctly print out only the name column, and not the entire hash of information on the object itself. How can I setup the show page to print out each tag separately for the model? The code that I have so far is below.
show.html.erb
<%= #user.user_profile.tags.each do |tag| %>
<%= tag.name %>
<% end %>
results shown on show page
#<ActsAsTaggableOn::Tag::ActiveRecord_Associations_CollectionProxy:0x2b7534d0> games [#<ActsAsTaggableOn::Tag id: 1, name: "games", created_at: "2017-08-25 15:54:30", updated_at: "2017-08-25 15:54:30", taggings_count: 1>] 1
console output
Rendering users/show.html.erb within layouts/application
UserProfile Load (8.0ms) SELECT "user_profiles".* FROM "user_profiles" WHERE "user_profiles"."user_id" = $1 LIMIT $2 [["user_id", 5], ["LIMIT", 1]]
ActsAsTaggableOn::Tag Load (15.0ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."context" = $3 [["taggable_id", 2], ["taggable_type", "UserProfile"], ["context", "tags"]]
ActsAsTaggableOn::Tagging Load (2.0ms) SELECT "taggings".* FROM "taggings" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 [["taggable_id", 2], ["taggable_type", "UserProfile"]]
ActsAsTaggableOn::Tag Load (25.0ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL) [["taggable_id", 2], ["taggable_type", "UserProfile"]]
user_profile.rb
class UserProfile < ApplicationRecord
acts_as_taggable
acts_as_taggable_on :abilities
end
Try
<% #user.user_profile.tags.each do |tag| %>
<%= tag.name %>
<% end %>
(without '=' after the '<%' in the first line)
Basically everytime a page loads this error pops up in the terminal. It doesn't seem to be causing any tangible issues:
NoMethodError (undefined method `each' for nil:NilClass): app/controllers/habits_controller.rb:8:in `sort'
I want to fix it though and I have a general idea how to.
When a new habit is created instead of its :order defaulting to nil it should default to the next highest integer.
HabitsController
def sort
params[:order].each do |id, order|
Habit.where(id: id).update_all(order: order)
end
render nothing: true
end
def habit_params
params.require(:habit).permit(
:user_id,
:trigger,
:tag_list,
:current_level,
:conceal,
:missed_days,
:target,
:reward,
:comment,
:commentable,
:like,
:likeable,
:action,
:order,
:date_started,
:missed_one,
:completed,
:completed_at,
:notes_text,
:notes_date,
:notable,
:note,
:committed => [],
levels_attributes: [
:missed_days,
:days_lost], notes_attributes: [:notable, :note, :notes_text, :notes_date, :_destroy])
end
schema
create_table "habits", force: true do |t|
t.integer "order"
end
rails c
[2] pry(main)> Habit.last
Habit Load (2.9ms) SELECT "habits".* FROM "habits" ORDER BY "habits"."id" DESC LIMIT 1
=> #<Habit:0x007f94e0da39b0
id: 12,
missed_days: 0,
conceal: false,
likes: nil,
date_started: Tue, 15 Sep 2015 00:00:00 EDT -04:00,
trigger: "wake up",
action: "run",
target: "2 miles",
reward: "eat dessert",
user_id: 2,
created_at: Tue, 15 Sep 2015 09:53:31 EDT -04:00,
updated_at: Tue, 15 Sep 2015 09:53:31 EDT -04:00,
order: nil,
completed_at: nil,
committed: ["sun", "mon", "tue", "wed", "thu", "fri", "sat", ""],
strike_date: nil,
missed_days_date: nil>
rails s
Started POST "/habits/sort" for 127.0.0.1 at 2015-09-15 10:02:36 -0400
Processing by HabitsController#sort as */*
User Load (2.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 2]]
Habit Load (0.4ms) SELECT "habits".* FROM "habits" WHERE "habits"."user_id" = $1 [["user_id", 2]]
ActsAsTaggableOn::Tag Load (0.5ms) SELECT "tags".* FROM "tags" WHERE (LOWER(name) = LOWER('ingrain'))
CACHE (0.0ms) SELECT "habits".* FROM "habits" WHERE "habits"."user_id" = $1 [["user_id", 2]]
Level Load (0.3ms) SELECT "levels".* FROM "levels" WHERE "levels"."habit_id" = $1 ORDER BY "levels"."id" ASC [["habit_id", 11]]
Level Load (0.3ms) SELECT "levels".* FROM "levels" WHERE "levels"."habit_id" = $1 ORDER BY "levels"."id" ASC [["habit_id", 12]]
Level Load (0.3ms) SELECT "levels".* FROM "levels" WHERE "levels"."habit_id" = $1 ORDER BY "levels"."id" ASC [["habit_id", 10]]
ActsAsTaggableOn::Tag Load (0.3ms) SELECT DISTINCT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."tagger_id" = $1 AND "taggings"."tagger_type" = $2 ORDER BY taggings_count desc LIMIT 20 [["tagger_id", 2], ["tagger_type", "User"]]
(0.3ms) SELECT COUNT(*) FROM "habits" WHERE "habits"."user_id" = $1 [["user_id", 2]]
Completed 500 Internal Server Error in 51ms
NoMethodError (undefined method `each' for nil:NilClass): app/controllers/habits_controller.rb:8:in `sort'
habit-sort.js
var update_orders, update_remote_orders;
update_remote_orders = function(orders) {
return $.ajax({
url: "/habits/sort",
type: "POST",
data: {
order: orders
},
success: function(data) {}
});
};
update_orders = function() {
var orders;
orders = {};
$("#sortable tr input.order:hidden").each(function(i, o) {
orders[$(o).attr("data-id")] = i;
return $(o).val(i);
});
return update_remote_orders(orders);
};
$(document).ready(function() {
update_orders();
$("#sortable").sortable({
axis: 'y',
handle: ".btn",
stop: function(ui, event) {
return update_orders();
}
});
});
I have a view that is iterating through a series of posts, and is running a count on the votes for each. I know how to do eager loading generally and how to use cache counters generally. But I can't figure out how to use the cache counter that comes with acts_as_votable (or I'm doing something else wrong.)
View:
<span class="votes">
<% if current_user.voted_for? link %>
<%= link_to like_link_path(link), class: "likes active", id: "link-#{link.id}", remote: true, method: :put do %>
<i class="fa fa-heart"></i> <%= link.cached_votes_total.to_s %>
<% end %>
<% else %>
<%= link_to like_link_path(link), class: "likes", id: "link-#{link.id}", remote: true, method: :put do %>
<i class="fa fa-heart-o"></i> <%= link.cached_votes_total.to_s %>
<% end %>
<% end %>
</span>
Terminal:
Link Load (0.4ms) SELECT "links".* FROM "links" ORDER BY "links"."score" DESC LIMIT 10 OFFSET 0
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (1)
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."voter_id" = $1 AND "votes"."voter_type" = $2 AND "votes"."votable_id" = $3 AND "votes"."votable_type" = $4 AND "votes"."vote_scope" IS NULL [["voter_id", 1], ["voter_type", "User"], ["votable_id", 1], ["votable_type", "Link"]]
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."voter_id" = $1 AND "votes"."voter_type" = $2 AND "votes"."votable_id" = $3 AND "votes"."votable_type" = $4 AND "votes"."vote_scope" IS NULL [["voter_id", 1], ["voter_type", "User"], ["votable_id", 2], ["votable_type", "Link"]]
Rendered home/index.html.erb within layouts/application (24.6ms)
Completed 200 OK in 60ms (Views: 56.9ms | ActiveRecord: 1.6ms)
Thanks!
It looked nothing abnormal to me. The voted_for? method is alias of voted_on?. Keep on reading the code you will find this method calls a votes.size > 0, which will trigger following queries to database. (I guess you have 2 links on your page, right?) So it has nothing to do with the cached counts fields.
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."voter_id" = $1 AND "votes"."voter_type" = $2 AND "votes"."votable_id" = $3 AND "votes"."votable_type" = $4 AND "votes"."vote_scope" IS NULL [["voter_id", 1], ["voter_type", "User"], ["votable_id", 1], ["votable_type", "Link"]]
(0.2ms) SELECT COUNT(*) FROM "votes" WHERE "votes"."voter_id" = $1 AND "votes"."voter_type" = $2 AND "votes"."votable_id" = $3 AND "votes"."votable_type" = $4 AND "votes"."vote_scope" IS NULL [["voter_id", 1], ["voter_type", "User"], ["votable_id", 2], ["votable_type", "Link"]]
P.S. The code is here: github: voter.rb.
May be that is not the best way, but it could help to preload user's votes for links in single database hit:
Somewhere in backend (e.g. User model) you may define method like
# votable - records, which were voted by user, links in the case
def preloaded_votes(votable)
#preloaded_votes ||= Vote.where(voter: self, votable: votable).group(:votable_id).count
end
this method will return hash like {votable_id1 => count1, votable_id2 => count2 }, where votable_idN means id of an element from votable argument for the method.
Change current call current_user.voted_for? link to preloaded counts current_user.preloaded_votes.key?(link.id)
This solution adds one more database hit, but allow to avoid N+1 queries. Also, additional SQL does not contain any tables joins. One possible way to improve here - add special index for this kind of queries.
I am trying to do a marking system for moderators, in which they can select each item as "editor pick".
I've added a :editor_pick column to photos table(boolean)
and added a form in the partial for each item to have a checkbox in it:
<% if controller_name == "photos" %>
<%= simple_form_for [#user, #photo] do |f| %>
<%= f.input :editor_pick, label: "Portada" %>
<%= f.submit "Pick" %>
<% end %>
<% end %>
after that, I required the new param in strong parameters in photos controller
It's redirecting me correctly after the update, but it's not saving the new value.
When I reload the page, the boolean is still false.
My controller actions:
def by_zone
#photo = Photo.find_by(params[:id])
#user = #photo.user
render :index
end
def update
#photo = Photo.friendly.find(params[:id])
if #photo.update_attributes(photo_params)
redirect_to [current_user, #photo], notice: 'El spot se ha actualizado.'
else
render 'edit'
end
end
Edit
def photo_params
params.require(:photo).permit(:editor_pick,:url,:remote_photo_url,:thumbnail_cache ,:order,:string_tags,:tag_list, :sponsored, :photo, :terms, :title,:description,:category_id,:zone_id, :crop_x, :crop_y, :crop_w, :crop_h, sponsors_attributes: [:name, :description, :web, :facebook, :twitter, :sponsored_avatar])
end
Params Edit
Started PATCH "/users/enrique-isasi-12/photos/rustic-plastic-table" for 127.0.0.1 at 2015-01-14 16:43:55 +0100
Processing by PhotosController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"wB2SmOT0zR0dwIIguRhzFdctY51LX333CzGYelxS4Hs=", "photo"=>{"editor_pick"=>"1"}, "commit"=>"Pick", "user_id"=>"enrique-isasi-12", "id"=>"rustic-plastic-table"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 5 ORDER BY "users"."id" ASC LIMIT 1
Notification Load (0.3ms) SELECT "notifications".* FROM "notifications" WHERE "notifications"."user_id" = $1 AND "notifications"."viewed_at" IS NULL ORDER BY "notifications"."created_at" DESC LIMIT 30 [["user_id", 5]]
Notification Load (0.2ms) SELECT "notifications".* FROM "notifications" WHERE "notifications"."user_id" = $1 AND (viewed_at IS NOT NULL) ORDER BY "notifications"."created_at" DESC LIMIT 30 [["user_id", 5]]
Photo Load (0.4ms) SELECT "photos".* FROM "photos" WHERE "photos"."slug" = 'rustic-plastic-table' ORDER BY "photos"."id" ASC LIMIT 1
(0.4ms) BEGIN
Category Load (0.3ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 ORDER BY "categories"."id" ASC LIMIT 1 [["id", 2]]
Zone Load (0.3ms) SELECT "zones".* FROM "zones" WHERE "zones"."id" = $1 ORDER BY "zones"."id" ASC LIMIT 1 [["id", 6]]
ActsAsTaggableOn::Tag Load (0.2ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL) [["taggable_id", 26], ["taggable_type", "Photo"]]
SQL (0.6ms) UPDATE "photos" SET "editor_pick" = $1, "updated_at" = $2 WHERE "photos"."id" = 26 [["editor_pick", true], ["updated_at", Wed, 14 Jan 2015 15:43:55 UTC +00:00]]
false ActsAsTaggableOn::Tag Load (0.2ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL) [["taggable_id", 26], ["taggable_type", "Photo"]]
(6.1ms) COMMIT
Redirected to http://localhost:3000/users/enrique-isasi-4/photos/rustic-plastic-table
Completed 302 Found in 31ms (ActiveRecord: 9.7ms)
Here's what happens:
I have in my controller:
#products = Spree::Product.all_active
And in the model:
Spree::Product.class_eval do
def self.all_active
includes(:master)
.where('available_on IS NULL OR available_on < ?', Time.now).where(deleted_at: nil)
end
end
And in the view I'm calling something that will look like this:
#products.each do |product|
product.images.each do |image|
image.attachment.url(:product)
end
end
The log is showing something along the lines like this for every single product:
Spree::Image Load (2.6ms) SELECT "spree_assets".* FROM "spree_assets" WHERE "spree_assets"."type" IN ('Spree::Image') AND "spree_assets"."viewable_id" = $1 AND "spree_assets"."viewable_type" = $2 ORDER BY "spree_assets"."position" ASC [["viewable_id", 9], ["viewable_type", "Spree::Variant"]]
Spree::Price Load (0.3ms) SELECT "spree_prices".* FROM "spree_prices" WHERE "spree_prices"."variant_id" = $1 AND "spree_prices"."currency" = 'USD' LIMIT 1 [["variant_id", 9]]
CACHE (0.3ms) SELECT "spree_zone_members".* FROM "spree_zone_members" WHERE "spree_zone_members"."zone_id" = $1 [["zone_id", 2]]
CACHE (0.0ms) SELECT "spree_countries".* FROM "spree_countries" WHERE "spree_countries"."id" IN (204, 49)
CACHE (0.2ms) SELECT "spree_shipping_methods".* FROM "spree_shipping_methods" INNER JOIN "spree_shipping_methods_zones" ON "spree_shipping_methods"."id" = "spree_shipping_methods_zones"."shipping_method_id" WHERE "spree_shipping_methods"."deleted_at" IS NULL AND "spree_shipping_methods_zones"."zone_id" = $1 [["zone_id", 2]]
CACHE (0.0ms) SELECT "spree_calculators".* FROM "spree_calculators" WHERE "spree_calculators"."calculable_type" = 'Spree::ShippingMethod' AND "spree_calculators"."calculable_id" IN (3, 2, 1)
(0.8ms) SELECT COUNT(*) FROM "spree_assets" WHERE "spree_assets"."type" IN ('Spree::Image') AND "spree_assets"."viewable_id" = $1 AND "spree_assets"."viewable_type" = $2 [["viewable_id", 1], ["viewable_type", "Spree::Variant"]]
I also have the bullet gem installed and it is recommending me to do:
N+1 Query detected
Spree::Variant => [:images]
Add to your finder: :include => [:images]
N+1 Query detected
Spree::Variant => [:default_price]
Add to your finder: :include => [:default_price]
I'm not sure where to place this .includes. to find out where Spree::Variant is being called I went to the Rails console:
2.0.0-p481 :001 > Spree::Product.first
Spree::Product Load (1.8ms) SELECT "spree_products".* FROM "spree_products" WHERE "spree_products"."deleted_at" IS NULL ORDER BY "spree_products"."id" ASC LIMIT 1
=> #<Spree::Product id: 1, name: "Ruby on Rails Tote", description: "Debitis facilis impedit natus eos qui vero. Ut qua...", available_on: "2014-07-04 05:44:50", deleted_at: nil, slug: "ruby-on-rails-tote", meta_description: nil, meta_keywords: nil, tax_category_id: 1, shipping_category_id: 1, created_at: "2014-07-04 05:44:51", updated_at: "2014-07-04 05:45:30">
2.0.0-p481 :002 > Spree::Product.first.images
Spree::Product Load (0.8ms) SELECT "spree_products".* FROM "spree_products" WHERE "spree_products"."deleted_at" IS NULL ORDER BY "spree_products"."id" ASC LIMIT 1
Spree::Variant Load (1.0ms) SELECT "spree_variants".* FROM "spree_variants" WHERE "spree_variants"."deleted_at" IS NULL AND "spree_variants"."product_id" = $1 AND "spree_variants"."is_master" = 't' LIMIT 1 [["product_id", 1]]
Spree::Image Load (0.8ms) SELECT "spree_assets".* FROM "spree_assets" WHERE "spree_assets"."type" IN ('Spree::Image') AND "spree_assets"."viewable_id" = $1 AND "spree_assets"."viewable_type" = $2 ORDER BY "spree_assets"."position" ASC [["viewable_id", 1], ["viewable_type", "Spree::Variant"]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Spree::Image id: 21, viewable_id: 1, viewable_type: "Spree::Variant", attachment_width: 360, attachment_height: 360, attachment_file_size: 31490, position: 1, attachment_content_type: "image/jpeg", attachment_file_name: "ror_tote.jpeg", type: "Spree::Image", attachment_updated_at: "2014-07-04 05:45:28", alt: nil, created_at: "2014-07-04 05:45:29", updated_at: "2014-07-04 05:45:29">, #<Spree::Image id: 22, viewable_id: 1, viewable_type: "Spree::Variant", attachment_width: 360, attachment_height: 360, attachment_file_size: 28620, position: 2, attachment_content_type: "image/jpeg", attachment_file_name: "ror_tote_back.jpeg", type: "Spree::Image", attachment_updated_at: "2014-07-04 05:45:29", alt: nil, created_at: "2014-07-04 05:45:30", updated_at: "2014-07-04 05:45:30">]>
Where would I add :images and :default_price within this context?
try:
Spree::Product.class_eval do
def self.all_active
includes(master: { products: :images } )
.where('available_on IS NULL OR available_on < ?', Time.now).where(deleted_at: nil)
end
end
includes can be used to fetch multiple models, nested or not.
For those that came here purely for the title:
Post.includes(:user, :group, sub_category: :category)