#=> Select "users".* FROM "users" INNER JOIN "posts" ON "posts"."user_id" = "users"."id"

You can use string in order to customize your joins

User.joins("LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id =")
#=> SELECT from users LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = 'Post' AND bookmarks.user_id =



Client.where("orders_count = '2'")
#=> SELECT * FROM clients where orders_count = 2

SQL Injections ! It’s recommended to use one of following methods


User.where ["name = ? and email = ? ", "Joe", ""]
#=> SELECT * FROM users where = 'Joe' AND = ''

ActiveRecord takes care of building query to avoid SQL injection


Fields can be symbols or strings. Values can be single values, arrays, or ranges

User.where {name: "Joe", email: ""}
#=> SELECT * FROM users WHERE name = 'Joe' AND email = ''

User.where {name: ["Alice", "Bob"]}
#=> SELECT * FROM users WHERE name IN ('Alice', 'Bob')

User.where {age: (1...10)}
#=> SELECT * FROM users WHERE age BETWEEN 1 AND 10


User.joins(:posts).where "posts.created_at < ?",

User.joins(:posts).where {"posts.published": true}

User.joins(:posts).where {posts: {published: true}}


Works in two unique ways

  1. takes a block so it can be used just like Array#select {|m| m.field == value}
  2. Modifies the SELECT statement for the query so that only certain fields are retrieved. :field
    #=> [#<Model id: nil, field: "value>]

    The agurment to the method can also be an array of fields :field, :other_field, :and_one_more
    #=> [#<Model id: nil, field: "value", other_field: "other_value", and_one_more: "and one more">]

    You can also use one or more strings, which will be used unchanged as SELECT fields. "field AS field_one", "other_field AS field_two"
    #=> [#<Model id: nil, field: "value", other_field: "other_value">]"field as field_one").first.field 
    #=> "value"



    Allows preloading, in the same way that includes does:

    User.preload :posts
    #=> SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 3)


    Allows to specify an order attribute ```ruby User.order :name #=> SELECT “users”.* FROM “users” ORDER BY “users”.”name” ASC

User.order email: :desc #=> SELECT “users”.* FROM “users” ORDER BY “users”.”name” DESC

User.order :name, email: desc #=> SELECT “users”.* FROM “users” ORDER BY “users”.”name” ASC, “users”.”email” DESC

## offset
User.offset 10
User.order(:name).offset 10 


Specifies a limit for the number of record returned

User.limit 10
#=> ...LIMIT 10


Specifies relationships to be included in the result set

users = User.includes :address 
users.each do |user|

allows you access the address attributes without firing any addition query. This will often result in a performance improvement over a simple join. You can include multiple relationships:

User.includes :orders, :address


User.includes(:posts).where " = ?", "example"

Note: includes works with associations name while references works with actual table name


Allows to specify a HAVING clause. Can’t work without group

Order.having("SUM(price) > 30").group :user_id


Allows to specify group attribute :name
#=> SELECT "users".* FROM "users" GROUP BY "users"."name"

Returns an array with distinct records based on the group attribute :id, :name
#=> [#<User id: 1, name: "Oscar">, #<User id: 2, name: "Oscar">, #<User id: 3, name: "Foo">] :name