Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
select не нужен, он просто лишний:Product.joins(:documents, :files, :etc).where(...).select('documents.type').pluck('documents.type')
joins и ничего — про includes. А в 4.0 появился ещё и references, а ещё есть eager_load. И какая между ними разница — знают немногие, почитать можно тут и тутmerge, который позволяет объединять условия из двух Relation'ов.# Constructs very scary SQL query to fetch latest conversations
# Select max message ids from latest sent and received messages, grouped by users.
sub_tmpl = Message.unscoped.select('MAX(messages.id) AS id')
latest_sent = sub_tmpl.select('messages.sent_messageable_id AS user_id')
.group(:sent_messageable_id).where(
received_messageable: current_user,
sent_messageable_type: 'User',
)
latest_rcvd = sub_tmpl.select('messages.received_messageable_id AS user_id')
.group(:received_messageable_id).where(
sent_messageable: current_user,
received_messageable_type: 'User',
)
sent_and_received = latest_sent.union(latest_rcvd)
latest_ids = Message.unscoped.select('MAX(last_message_ids.id)')
.from("(#{sent_and_received.to_sql}) last_message_ids")
.group('user_id')
@messages = Message.where(id: latest_ids).page(params[:page])product.lines
Получается и нагляднее и эффективнее.
scope :lines, ->{Line.where(product_id: id)}
@products = Product.last(10)
- @products.each do |product| # find_each тут получше будет
%td
= product.name
%td
= product.type
реальной сортировки не происходит
В Rails 4 all≡scoped и прострелить конечность так просто не получится, разве что вместо all вызвать to_a, но это совсем тяжёлый случай.
Product.all.find{|p| p.id == 42}метод #find делегируется к какому классу?? Ага. А как Вы думаете, каким образом к этому классу будет преобразовано relation Product.all? ;-)
# ...
include FinderMethods, Calculations, SpawnMethods, QueryMethods, Batches, Explain, Delegation
# ...
def to_a
load
@records
end
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a
def array_delegable?(method)
Array.method_defined?(method) && BLACKLISTED_ARRAY_METHODS.exclude?(method)
end
def method_missing(method, *args, &block)
if @klass.respond_to?(method)
scoping { @klass.public_send(method, *args, &block) }
elsif array_delegable?(method)
to_a.public_send(method, *args, &block)
elsif arel.respond_to?(method)
arel.public_send(method, *args, &block)
else
super
end
end
BLACKLISTED_ARRAY_METHODS = [
:compact!, :flatten!, :reject!, :reverse!, :rotate!, :map!,
:shuffle!, :slice!, :sort!, :sort_by!, :delete_if,
:keep_if, :pop, :shift, :delete_at, :compact, :select!
].to_set
Совет про default_scope
product.documents.map{…}
Проблема в обычных итераторах, применённых на Relation только одна: они вытаскивают записи из БД поштучно.
ActiveRecord немного про грабли, Relations и индексы