rails的接口查询详解
Retrieving Objects from the Database
find
"find"是一种常用的数据库查询办法,在Rails中被用于从数据库中查找单个记载。它能够接纳一个主键作为参数,也能够接纳一组条件参数。
以下是"find"办法的运用办法:
# 运用主键查找单个记载
Model.find(1)
# 运用条件参数查找单个记载
Model.find_by(name: 'John')
在上面的示例中,"Model"是你需求查询记载的Rails模型,"find"办法能够接纳一个主键作为参数,例如第一个示例中的"1",以查找具有指定主键的记载。假如找不到这样的记载,"find"办法会引发一个"ActiveRecord::RecordNotFound"反常。
"find"办法还能够接纳一组条件参数,例如第二个示例中的"name: 'John'",以查找满意这些条件的单个记载。假如找不到这样的记载,"find_by"办法会回来"nil",而不是引发反常。
总归,"find"办法是一个常用的用于从数据库中查找单个记载的办法。
take
irb> customer = Customer.take
=> #<Customer id: 1, first_name: "Lifo">
这行代码运用Active Record的take
办法从数据库中检索一个Customer
目标,并将其分配给名为customer
的变量。take
办法不承受参数,它将从数据库中随机挑选一个目标,而不考虑任何特定的排序或挑选条件。
假如数据库中没有任何Customer
目标,则customer
变量将被分配为nil
。假如数据库中有多个Customer
目标,则take
办法将从这些目标中随机挑选一个目标。
这个代码片段能够用于在Rails应用程序中获取一个随机的客户端目标,并将其用于某些特定的使命。例如,假如咱们有一个名为"Customer of the Day"的功用,能够运用take
办法从数据库中随机挑选一个客户端,并将其作为今日的"客户端之星"。
需求留意的是,运用take
办法时,不能确保总是回来相同的目标,由于它是从数据库中随机挑选一个目标。假如需求依照特定的次序或条件检索目标,则应运用其他查询办法,如find
、where
和order
等。
first
在Active Record中,first
是一种查询办法,它用于检索契合条件的第一个目标。它能够与其他查询办法(如where
和order
)一同运用,以指定特定的条件和次序来检索目标。
例如,咱们能够运用first
办法从数据库中检索第一个创立的Product
目标。代码如下:
@oldest_product = Product.order(created_at: :asc).first
这个代码片段运用了Active Record的order
和first
办法来构建查询。order
办法依照创立时刻(created_at
)的升序排序,first
办法回来第一个目标。
在查询中,假如没有契合条件的目标,则first
办法将回来nil
。
first
办法还能够承受一个可选参数,用于指定要回来的目标数量。例如,咱们能够运用first(5)
办法检索最早创立的5个Product
目标。
需求留意的是,first
办法回来的目标可能会跟着数据库中数据的改动而改动。假如需求依照特定的次序或条件检索目标,则应运用其他查询办法,如find
、where
和order
等。
last
在Active Record中,last
是一种查询办法,它用于检索契合条件的最终一个目标。它能够与其他查询办法(如where
和order
)一同运用,以指定特定的条件和次序来检索目标。
例如,咱们能够运用last
办法从数据库中检索最终一个创立的Product
目标。代码如下:
@latest_product = Product.order(created_at: :desc).last
这个代码片段运用了Active Record的order
和last
办法来构建查询。order
办法依照创立时刻(created_at
)的降序排序,last
办法回来最终一个目标。
在查询中,假如没有契合条件的目标,则last
办法将回来nil
。
last
办法还能够承受一个可选参数,用于指定要回来的目标数量。例如,咱们能够运用last(5)
办法检索最近创立的5个Product
目标。
需求留意的是,last
办法回来的目标可能会跟着数据库中数据的改动而改动。假如需求依照特定的次序或条件检索目标,则应运用其他查询办法,如find
、where
和order
等。
find_by
在Active Record中,find_by
是一种查询办法,它用于查找契合条件的第一个目标。与where
办法不同的是,find_by
回来的是一个目标而不是一个联系调集。假如没有契合条件的目标,则回来nil
。
find_by
办法需求传递一个参数,用于指定查询条件。查询条件能够是任何一个模型中界说的特点,例如:
@product = Product.find_by(name: 'Widget')
这个查询将回来契合name
特点为'Widget'的第一个Product
目标。
查询条件也能够是多个特点,例如:
@product = Product.find_by(name: 'Widget', price: 10.99)
这个查询将回来契合name
特点为'Widget'且price
特点为10.99的第一个Product
目标。
需求留意的是,find_by
办法只回来契合条件的第一个目标。假如需求回来一切契合条件的目标,则应运用where
办法。
别的,能够运用find_by!
办法来查找契合条件的第一个目标,假如没有找到,则会抛出ActiveRecord::RecordNotFound
反常。
find_each
在Active Record中,find_each
是一种查询办法,它用于按批次检索很多记载。与find
办法不同的是,find_each
办法会将成果分批回来,以防止加载很多数据时内存不足的状况。
find_each
办法需求传递一个块(block),块中的代码将应用于每个批次中的记载。例如:
Product.find_each(batch_size: 500) do |product|
# 处理每个产品的代码
end
这个代码片段将每个Product
目标分批检索,每个批次中包括500个记载。关于每个批次中的记载,块中的代码将被调用一次。
find_each
办法还能够承受其他选项,例如:
start
:指定查询开始的记载ID,默以为1。finish
:指定查询完毕的记载ID,默以为nil
,表明查询到最终一条记载。batch_size
:指定每个批次中记载的数量,默以为1000。order
:指定记载的排序办法,默以为主键的升序排序。
需求留意的是,find_each
办法回来的成果是一个Enumerator
目标。假如需求将成果作为数组回来,则应运用to_a
办法,例如:
products = Product.find_each(batch_size: 500).to_a
别的,find_each
办法仅适用于根据主键的查询。假如需求运用其他查询条件,应运用where
办法。
假定咱们有一个名为Product
的模型,其间包括id
、name
和price
特点。咱们想要运用find_each
办法检索id
特点在2000到5000之间的一切产品,并依照价格(price
)降序排序。咱们能够这样完成:
Product.where(id: 2000..5000).order(price: :desc).find_each(start: 2000, batch_size: 500) do |product|
# 处理每个产品的代码
end
这个代码片段运用了where
办法指定了查询条件,运用order
办法指定了排序办法。一同,咱们运用了start
选项来指定开始的记载ID为2000,运用了batch_size
选项来指定每个批次中包括500条记载。
在块中,咱们能够运用product
变量拜访每个批次中的记载,并履行必要的处理。
需求留意的是,find_each
办法回来的成果是一个Enumerator
目标。假如需求将成果作为数组回来,则应运用to_a
办法,例如:
products = Product.where(id: 2000..5000).order(price: :desc).find_each(start: 2000, batch_size: 500).to_a
别的,find_each
办法仅适用于根据主键的查询。假如需求运用其他查询条件,应运用where
办法。
Conditions
Pure String Conditions
在Active Record中,能够运用“纯字符串条件”(Pure String Conditions)来指定查询条件。纯字符串条件是指用字符串表明的查询条件,能够在where
办法中直接运用。
例如,咱们能够运用以下字符串条件来查询Product
模型中价格在10到20之间的产品:
Product.where("price BETWEEN 10 AND 20")
这个查询中,咱们运用了字符串"price BETWEEN 10 AND 20"
作为查询条件。这个字符串指定了价格在10到20之间的产品。运用where
办法将这个字符串作为参数传递给Product
模型,即可履行查询。
需求留意的是,运用纯字符串条件时,应确保字符串中的查询句子是安全的,以防止SQL注入等安全问题。假如字符串中包括用户输入的内容,应运用参数化查询(Parameterized Queries)来确保查询的安全性。
除了where
办法,纯字符串条件还能够用于其他查询办法,如find_by_sql
和joins
等。可是,尽可能地运用Active Record的查询API(如where
、joins
、group
、order
等)来构建查询,能够使查询更易于阅览、保护和安全。
Array Conditions
在Active Record中,能够运用“数组条件”(Array Conditions)来指定查询条件。数组条件是指将查询条件表明为数组办法,能够在where
办法中直接运用。
例如,咱们能够运用以下数组条件来查询Product
模型中价格在10到20之间的产品:
Product.where(price: 10..20)
这个查询中,咱们运用了price: 10..20
作为查询条件。这个条件指定了价格在10到20之间的产品。运用where
办法将这个条件作为参数传递给Product
模型,即可履行查询。
数组条件还能够用于指定多个查询条件,例如:
Product.where("name LIKE ?", "%widget%").where(price: 10..20)
这个查询中,咱们运用了两个条件来查询产品。第一个条件运用了纯字符串条件,查询称号中包括“widget”的产品;第二个条件运用了数组条件,查询价格在10到20之间的产品。
需求留意的是,数组条件只适用于等于(=
)操作符和规模(IN
)操作符。假如需求运用其他操作符,应运用纯字符串条件。
别的,数组条件还能够用于指定NULL值的查询条件,例如:
Product.where(price: nil)
这个查询将回来价格为空(NULL)的产品。要查询非空值,能够运用where.not
办法,例如:
Product.where.not(price: nil)
这个查询将回来价格非空的产品。
总归,数组条件是一种便利、易于了解和安全的查询办法,能够使查询代码愈加简练和易于保护。
Placeholder Conditions
在Active Record中,能够运用“占位符条件”(Placeholder Conditions)来指定查询条件。占位符条件是指运用?
占位符来表明查询条件,能够在where
办法中直接运用。
例如,咱们能够运用以下占位符条件来查询Product
模型中价格在10到20之间的产品:
Product.where("price BETWEEN ? AND ?", 10, 20)
这个查询中,咱们运用了字符串"price BETWEEN ? AND ?"
作为查询条件,其间?
表明占位符。运用where
办法将这个字符串和两个参数(10和20)作为参数传递给Product
模型,即可履行查询。
占位符条件还能够用于指定多个查询条件,例如:
Product.where("name LIKE ? AND price BETWEEN ? AND ?", "%widget%", 10, 20)
这个查询中,咱们运用了三个占位符来查询产品。第一个占位符表明称号中包括“widget”的产品;第二个占位符表明价格大于等于10的产品;第三个占位符表明价格小于等于20的产品。
占位符条件能够有效地防止SQL注入等安全问题,由于查询条件中的值不会被直接拼接到查询句子中,而是运用占位符传递给数据库引擎进行处理。
需求留意的是,占位符条件不能用于指定列名、表名等标识符,只能用于指定查询条件的值。假如需求运用列名或表名等标识符,应运用纯字符串条件。
总归,占位符条件是一种便利、安全和可读性较高的查询办法,能够防止SQL注入等安全问题,主张在查询中运用。
Conditions That Use LIKE
在Active Record中,能够运用LIKE
操作符和占位符条件来进行含糊查询。LIKE
操作符用于匹配字符串,能够在where
办法中直接运用。
例如,咱们能够运用以下条件来查询Product
模型中称号包括“widget”的产品:
Product.where("name LIKE ?", "%widget%")
这个查询中,咱们运用了字符串"name LIKE ?"
作为查询条件,其间?
表明占位符。运用where
办法将这个字符串和"%widget%"
作为参数传递给Product
模型,即可履行查询。"%widget%"
表明称号中包括“widget”的字符串,%
表明匹配恣意字符。
LIKE
操作符还支撑以下通配符:
%
:匹配恣意字符(包括空格)。_
:匹配单个字符。[]
:匹配方括号内恣意一个字符。[^]
:匹配不在方括号内的恣意一个字符。
例如,咱们能够运用以下条件来查询称号以“w”最初、后边跟着两个恣意字符、然后是“dget”的产品:
Product.where("name LIKE ?", "w__dget")
这个查询中,咱们运用了字符串"name LIKE ?"
作为查询条件,其间?
表明占位符。运用where
办法将这个字符串和"w__dget"
作为参数传递给Product
模型,即可履行查询。"w__dget"
中的两个下划线表明匹配两个恣意字符。
需求留意的是,LIKE
操作符比较消耗核算资源,由于它需求对每条记载进行形式匹配。假如匹配的字符串很长或匹配的规模很大,查询功能可能会受到影响。
总归,LIKE
操作符是一种十分有用的查询条件,能够用来进行含糊查询。在运用LIKE
操作符时,应该留意通配符的运用,以及查询功能的影响。
Hash Conditions
在Active Record中,能够运用哈希条件(Hash Conditions)来指定查询条件。哈希条件是指运用哈希表(Hash)来表明查询条件,能够在where
办法中直接运用。
例如,咱们能够运用以下哈希条件来查询Product
模型中价格在10到20之间的产品:
Product.where(price: 10..20)
这个查询中,咱们运用了一个哈希表{price: 10..20}
作为查询条件,其间price
是列名,10..20
表明价格在10到20之间的规模。运用where
办法将这个哈希表作为参数传递给Product
模型,即可履行查询。
哈希条件还能够用于指定多个查询条件,例如:
Product.where(name: "widget", price: 10..20)
这个查询中,咱们运用了一个哈希表{name: "widget", price: 10..20}
来查询产品。这个哈希表表明称号为“widget”且价格在10到20之间的产品。
哈希条件的长处是可读性高,能够直接运用列名作为键名,不需求运用字符串或占位符。一同,哈希条件也能够指定多个查询条件,愈加灵敏。
需求留意的是,哈希条件只能用于指定持平条件、规模条件和空值条件,不能用于指定其他类型的条件,例如含糊查询和杂乱的逻辑查询。假如需求运用这些条件,应该运用字符串条件或其他类型的查询条件。
总归,哈希条件是一种便利、可读性高的查询办法,能够用于指定持平条件、规模条件和空值条件。在查询中运用哈希条件能够使代码愈加简练、易读。
NOT Conditions
在Active Record中,能够运用not
办法来对查询条件取反。not
办法用于将查询条件取反,能够在where
办法中运用。
例如,咱们能够运用以下条件来查询Product
模型中不是价格在10到20之间的产品:
Product.where.not(price: 10..20)
这个查询中,咱们运用了where.not
办法来表明价格不在10到20之间的条件。运用where.not
办法将这个条件作为参数传递给Product
模型,即可履行查询。
not
办法还能够用于对杂乱条件进行取反,例如:
Product.where.not("name LIKE ?", "%widget%").where.not(price: 10..20)
这个查询中,咱们运用了两个where.not
办法来查询称号不包括“widget”且价格不在10到20之间的产品。第一个where.not
办法运用字符串条件进行含糊查询,第二个where.not
办法运用哈希条件表明价格不在10到20之间。运用where.not
办法将这个条件作为参数传递给Product
模型,即可履行查询。
需求留意的是,not
办法只能对简略条件和杂乱条件的组合进行取反,不能对杂乱的逻辑条件进行取反。假如需求对杂乱的逻辑条件进行取反,应该运用逻辑运算符(例如AND
、OR
、NOT
)来组合条件。
总归,not
办法是一种对查询条件取反的办法,能够用于简略条件和杂乱条件的组合。在运用not
办法时,应该留意条件的取反办法和逻辑联系,以防止呈现查询过错。
OR Conditions
在Active Record中,能够运用or
办法来对查询条件进行逻辑或(OR)运算。or
办法用于将两个查询条件进行逻辑或运算,能够在where
办法中运用。
例如,咱们能够运用以下条件来查询Product
模型中价格小于10或价格大于20的产品:
Product.where("price < 10").or(Product.where("price > 20"))
这个查询中,咱们运用了where
办法和or
办法来查询价格小于10或价格大于20的产品。第一个where
办法运用字符串条件查询价格小于10的产品,第二个where
办法运用字符串条件查询价格大于20的产品。运用or
办法将这两个查询条件进行逻辑或运算,即可得到价格小于10或价格大于20的产品列表。
or
办法还能够和其他查询办法一同运用,例如:
Product.where("name LIKE ?", "%widget%").or(Product.where("price < 10"))
这个查询中,咱们运用了where
办法和or
办法来查询称号包括“widget”或价格小于10的产品。第一个where
办法运用字符串条件进行含糊查询,第二个where
办法运用字符串条件查询价格小于10的产品。运用or
办法将这两个查询条件进行逻辑或运算,即可得到称号包括“widget”或价格小于10的产品列表。
需求留意的是,or
办法只能用于两个查询条件的逻辑或运算,不能用于多个查询条件的逻辑或运算。假如需求对多个查询条件进行逻辑或运算,应该运用where
办法和逻辑运算符(例如OR
)来组合条件。
总归,or
办法是一种对查询条件进行逻辑或运算的办法,能够用于两个查询条件的组合。在运用or
办法时,应该留意逻辑联系和条件的组合办法,以防止呈现查询过错。
AND Conditions
在Active Record中,能够运用where
办法对查询条件进行逻辑与(AND)运算。where
办法用于将多个查询条件进行逻辑与运算,能够经过屡次调用where
办法来完成。
例如,咱们能够运用以下条件来查询Product
模型中称号包括“widget”且价格在10到20之间的产品:
Product.where("name LIKE ?", "%widget%").where(price: 10..20)
Product.where("name LIKE ?", "%widget%").where(price: 10..20)
这个查询中,咱们运用了两次where
办法来查询称号包括“widget”且价格在10到20之间的产品。第一个where
办法运用字符串条件进行含糊查询,第二个where
办法运用哈希条件查询价格在10到20之间的产品。运用两次where
办法将这两个查询条件进行逻辑与运算,即可得到称号包括“widget”且价格在10到20之间的产品列表。
where
办法能够和其他查询办法一同运用,例如:
Product.where("name LIKE ?", "%widget%").where.not(price: 10..20)
这个查询中,咱们运用了两次where
办法来查询称号包括“widget”且价格不在10到20之间的产品。第一个where
办法运用字符串条件进行含糊查询,第二个where
办法运用not
办法将价格在10到20之间的条件取反。运用两次where
办法将这两个查询条件进行逻辑与运算,即可得到称号包括“widget”且价格不在10到20之间的产品列表。
需求留意的是,where
办法能够屡次调用来完成多个查询条件的逻辑与运算。在运用where
办法时,应该留意逻辑联系和条件的组合办法,以防止呈现查询过错。
总归,where
办法是一种对查询条件进行逻辑与运算的办法,能够经过屡次调用来完成多个查询条件的组合。在运用where
办法时,应该留意逻辑联系和条件的组合办法,以防止呈现查询过错。
Ordering
在Active Record中,能够运用order
办法来对查询成果进行排序。order
办法用于依照指定的字段对查询成果进行排序,能够在all
、where
、find_by
等查询办法中运用。
例如,咱们能够运用以下条件来查询Product
模型中价格从低到高排序的产品:
Product.order(price: :asc)
这个查询中,咱们运用了order
办法来对查询成果依照价格从低到高排序。运用哈希条件将排序字段和排序办法传递给order
办法,即可对查询成果进行排序。
order
办法还能够对多个字段进行排序,例如:
Product.order(price: :asc, created_at: :desc)
这个查询中,咱们运用了order
办法来对查询成果先依照价格从低到高排序,再依照创立时刻从新到旧排序。运用哈希条件将排序字段和排序办法传递给order
办法,即可对查询成果进行多字段排序。
需求留意的是,order
办法只能对查询成果进行排序,不能对查询条件进行排序。假如需求对查询条件进行排序,应该运用where
办法和排序字段来完成。
总归,order
办法是一种对查询成果进行排序的办法,能够依照指定的字段和排序办法对查询成果进行排序。在运用order
办法时,应该留意排序字段和排序办法的传递办法,以得到正确的排序成果。
Selecting Specific Fields
在Active Record中,能够运用select
办法来挑选查询成果中的特定字段。select
办法用于从查询成果中挑选指定的字段,能够在all
、where
、find_by
等查询办法中运用。
例如,咱们能够运用以下条件来查询Product
模型中称号和价格字段的产品:
Product.select(:name, :price)
这个查询中,咱们运用了select
办法来挑选称号和价格字段。运用符号或字符串传递要挑选的字段名给select
办法,即可从查询成果中挑选指定的字段。
select
办法还能够挑选核算字段或运用别号,例如:
Product.select("name, price, price * 0.8 AS discounted_price")
这个查询中,咱们运用了select
办法来挑选称号、价格和打折后价格(运用价格乘以0.8核算)。运用字符串传递要挑选的字段名或核算表达式给select
办法,即可从查询成果中挑选指定的字段或核算字段。
需求留意的是,select
办法只能挑选查询成果中已有的字段或核算字段,不能挑选不存在的字段。假如需求挑选不存在的字段,应该运用select_raw
办法和SQL句子来完成。
总归,select
办法是一种从查询成果中挑选特定字段的办法,能够挑选已有的字段或核算字段,并运用别号来改动字段名。在运用select
办法时,应该留意挑选字段的姓名和核算表达式的正确性,以得到正确的查询成果。
Limit and Offset
在Active Record中,能够运用limit
和offset
办法来约束查询成果的数量和偏移量。limit
办法用于约束查询成果的数量,offset
办法用于设置查询成果的偏移量,能够在all
、where
、find_by
等查询办法中运用。
例如,咱们能够运用以下条件来查询Product
模型中前10个产品:
Product.limit(10)
这个查询中,咱们运用了limit
办法来约束查询成果的数量为10。运用整数传递要约束的数量给limit
办法,即可对查询成果进行数量约束。
offset
办法用于设置查询成果的偏移量,例如:
Product.offset(10).limit(10)
这个查询中,咱们运用了offset
办法来设置查询成果的偏移量为10,然后运用limit
办法来约束查询成果的数量为10。运用整数传递要设置的偏移量给offset
办法,即可对查询成果进行偏移量设置。
需求留意的是,offset
和limit
办法的调用次序十分重要。假如先调用limit
办法再调用offset
办法,偏移量会被疏忽,数量约束会应用于整个查询成果。因而,在运用offset
和limit
办法时,应该一直依照正确的次序进行调用。
总归,limit
和offset
办法是一种约束查询成果数量和偏移量的办法,能够对查询成果进行分页和约束。在运用这些办法时,应该留意调用的次序和传递的参数,以得到正确的查询成果。
Group
在Active Record中,能够运用group
办法来对查询成果进行分组。group
办法用于依照指定的字段对查询成果进行分组,能够在all
、where
、find_by
等查询办法中运用。
例如,咱们能够运用以下条件来查询Order
模型中每个用户的总订单金额:
Order.select("user_id, sum(price) as total_price").group(:user_id)
这个查询中,咱们运用了select
办法来挑选用户ID和总订单金额字段,并运用sum
函数来核算每个用户的总订单金额。然后运用group
办法来依照用户ID对查询成果进行分组。
group
办法还能够依照多个字段进行分组,例如:
Order.select("user_id, product_id, sum(price) as total_price").group(:user_id, :product_id)
这个查询中,咱们运用了select
办法来挑选用户ID、产品ID和总订单金额字段,并运用sum
函数来核算每个用户和产品的总订单金额。然后运用group
办法来依照用户ID和产品ID对查询成果进行分组。
需求留意的是,group
办法只能对查询成果进行分组,不能对查询条件进行分组。假如需求对查询条件进行分组,应该运用having
办法和SQL句子来完成。
总归,group
办法是一种对查询成果进行分组的办法,能够依照指定的字段对查询成果进行分组,并运用聚合函数核算每个分组的值。在运用group
办法时,应该留意挑选分组的字段和聚合函数的正确性,以得到正确的查询成果。
Having
在Active Record中,能够运用having
办法来对分组后的查询成果进行挑选。having
办法用于在分组后对分组成果进行挑选,能够在group
办法后运用。
例如,咱们能够运用以下条件来查询Order
模型中每个用户的总订单金额大于100的用户ID和总订单金额:
Order.select("user_id, sum(price) as total_price").group(:user_id).having("sum(price) > 100")
这个查询中,咱们运用了select
办法来挑选用户ID和总订单金额字段,并运用sum
函数来核算每个用户的总订单金额。然后运用group
办法来依照用户ID对查询成果进行分组。最终运用having
办法来挑选总订单金额大于100的用户。
having
办法还能够运用多个挑选条件,例如:
Order.select("user_id, product_id, sum(price) as total_price").group(:user_id, :product_id).having("sum(price) > 100 and count(*) > 2")
这个查询中,咱们运用了select
办法来挑选用户ID、产品ID和总订单金额字段,并运用sum
函数来核算每个用户和产品的总订单金额。然后运用group
办法来依照用户ID和产品ID对查询成果进行分组。最终运用having
办法来挑选总订单金额大于100且订单数量大于2的用户和产品。
需求留意的是,having
办法只能在group
办法后运用,用于对分组成果进行挑选。假如需求对查询条件进行挑选,应该运用where
办法。
总归,having
办法是一种对分组后的查询成果进行挑选的办法,能够依照指定的条件对分组成果进行挑选。在运用having
办法时,应该留意挑选条件的正确性,以得到正确的查询成果。