现在的位置: 首页 > 综合 > 正文

rails active record querying

2013年03月17日 ⁄ 综合 ⁄ 共 3920字 ⁄ 字号 评论关闭

Retrieving Multiple Objects in Batches

find_each
User.find_each(:batch_size => 5000) do |user|
  NewsLetter.weekly_deliver(user)
end

User.find_each(:batch_size => 5000, :start => 2000) do |user|
  NewsLetter.weekly_deliver(user)
end

:start option allows you to configure the first ID of the sequence if the lowest is not the one you need.
find_each accepts the same options as the regularfind method. However,
:order and :limit are needed internally and hence not allowed to be passed explicitly.

Conditions

Client.where("orders_count = ?", params[:orders])

instead of

Client.where("orders_count = #{params[:orders]}")

because of SQL injection

Client.where(:created_at => (params[:start_date].to_date)..(params[:end_date].to_date))

Hash Conditions

Subset Conditions
Client.where(:orders_count => [1,3,5])

Ordering

Client.order("orders_count ASC, created_at DESC")

Selecting Specific Fields

Client.select("viewable_by, locked")

Be careful because this also means you’re initializing a model object with only the fields that you’ve selected. If you attempt to access a field that is not in the initialized record you’ll receive:

ActiveRecord::MissingAttributeError: missing attribute: <attribute>
Client.select("DISTINCT(name)")

Pessimistic Locking
Item.transaction do
  i = Item.lock.first
  i.name = 'Jones'
  i.save
end

Item.transaction
do
  i
= Item.lock(
"LOCK
IN SHARE MODE"
).find(1)
  i.increment!(:views)
end

Joining Tables

Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')

Joining a Single Association
Category.joins(:posts)

SELECT categories.* FROM categories
  INNER JOIN posts ON posts.category_id = categories.id

Joining Multiple Associations
Post.joins(:category, :comments)

SELECT posts.* FROM posts
  INNER JOIN categories ON posts.category_id = categories.id
  INNER JOIN comments ON comments.post_id = posts.id

Joining Nested Associations (Single Level)

Post.joins(:comments => :guest)

 Joining Nested Associations (Multiple Level)
Category.joins(:posts => [{:comments => :guest}, :tags])

Specifying Conditions on the Joined Tables

time_range = (Time.now.midnight - 1.day)..Time.now.midnight
Client.joins(:orders).where('orders.created_at' => time_range)

time_range = (Time.now.midnight - 1.day)..Time.now.midnight
Client.joins(:orders).where(:orders => {:created_at => time_range})

Eager Loading Associations

Active Record lets you specify in advance all the associations that are going to be loaded. This is possible by specifying the includes method
of the Model.find call.
With includes,
Active Record ensures that all of the specified associations are loaded using the minimum possible number of queries.

clients = Client.includes(:address).limit(10)
 
clients.each do |client|
  puts client.address.postcode
end

SELECT * FROM clients LIMIT 10
SELECT addresses.* FROM addresses
  WHERE (addresses.client_id IN (1,2,3,4,5,6,7,8,9,10))

Eager Loading Multiple Associations

Post.includes(:category, :comments)

Category.includes(:posts => [{:comments => :guest}, :tags]).find(1)

Dynamic Finders

For every field (also known as an attribute) you define in your table, Active Record provides a finder method. If you have a field called first_name on
your Client model
for example, you getfind_by_first_name and find_all_by_first_name for
free from Active Record. If you have also have a locked field
on the Client model,
you also get find_by_locked and
find_all_by_locked


If you want to find both by name and locked, you can chain these finders together by simply typingand between
the fields for example Client.find_by_first_name_and_locked("Ryan",
true)


There’s
another set of dynamic finders that let you find or create/initialize objects if they aren’t found.

Finding by SQL

Client.find_by_sql("SELECT * FROM clients
  INNER JOIN orders ON clients.id = orders.client_id
  ORDER clients.created_at desc")

find_by_sql has
a close relative called connection#select_allselect_all will
retrieve objects from the database using custom SQL just
like find_by_sql but
will not instantiate them. Instead, you will get an array of hashes where each hash indicates a record.


Existence of Objects

Client.exists?(1)

Client.exists?(1,2,3)
# or
Client.exists?([1,2,3])

Client.where(:first_name => 'Ryan').exists?

Client.exists?

Calculations

 If you want to be more specific and find all the clients with their age present in the database you can use Client.count(:age).

Client.average("orders_count")

minimum maximun sum

抱歉!评论已关闭.