在执行 ActiveRecord 查询时,如何优先处理具有标记为 true 的属性然后 created_at desc 之后的记录?
When doing an ActiveRecord query, how do I prioritize a record that has an attribute marked as true first then created_at desc after?
我在 Question
上有一堆 Answers
。
我想做的是分两步对每个问题的答案进行排序:
- 如果有一个可接受的答案,return 第一个,然后...
- Return 其余答案,
created_at: :desc
如果#1 不存在,则默认为 2。
这是我试过的方法,但没有用:
[21] pry(main)> q.answers.order(:accepted, created_at: :desc)
[23] pry(main)> q.answers.order(accepted: true, created_at: :asc).inspect
ArgumentError: Direction "true" is invalid. Valid directions are: [:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]
from /gems/activerecord-5.0.0.rc1/lib/active_record/relation/query_methods.rb:1164:in `block (2 levels) in validate_order_args'
[24] pry(main)> q.answers.order(accepted: "true", created_at: :asc).inspect
ArgumentError: Direction "true" is invalid. Valid directions are: [:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]
from gems/activerecord-5.0.0.rc1/lib/active_record/relation/query_methods.rb:1164:in `block (2 levels) in validate_order_args'
如何实现?
编辑 1
这是一个 accepted: true
:
的答案示例
[26] pry(main)> q.answers.first
=> #<Answer:0x007f997d7a5a80
id: 69,
body:
"public static Process CreateProcessAsUser(string filename, string args)\r\n {\r\n var hToken = WindowsIdentity.GetCurrent().Token;\r\n var hDupedToken = IntPtr.Zero;\r\n\r\n var pi = new PROCESS_INFORMATION();\r\n var sa = new SECURITY_ATTRIBUTES();\r\n sa.Length = Marshal.SizeOf(sa);\r\n\r\n try\r\n {\r\n if (!DuplicateTokenEx(\r\n hToken,\r\n GENERIC_ALL_ACCESS,\r\n ref sa,\r\n (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,\r\n (int)TOKEN_TYPE.TokenPrimary,\r\n ref hDupedToken\r\n ))\r\n throw new Win32Exception(Marshal.GetLastWin32Error());\r\n\r\n var si = new STARTUPINFO();\r\n si.cb = Marshal.SizeOf(si);\r\n ",
user_id: 1547,
question_id: 47,
created_at: Wed, 15 Jun 2016 05:20:11 UTC +00:00,
updated_at: Mon, 20 Jun 2016 22:34:08 UTC +00:00,
accepted: true,
language: nil,
comments_count: nil>
您需要将字符串传递给 order
方法:
q.answers.order("accepted = true DESC").order(:created_at)
我在 Question
上有一堆 Answers
。
我想做的是分两步对每个问题的答案进行排序:
- 如果有一个可接受的答案,return 第一个,然后...
- Return 其余答案,
created_at: :desc
如果#1 不存在,则默认为 2。
这是我试过的方法,但没有用:
[21] pry(main)> q.answers.order(:accepted, created_at: :desc)
[23] pry(main)> q.answers.order(accepted: true, created_at: :asc).inspect
ArgumentError: Direction "true" is invalid. Valid directions are: [:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]
from /gems/activerecord-5.0.0.rc1/lib/active_record/relation/query_methods.rb:1164:in `block (2 levels) in validate_order_args'
[24] pry(main)> q.answers.order(accepted: "true", created_at: :asc).inspect
ArgumentError: Direction "true" is invalid. Valid directions are: [:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]
from gems/activerecord-5.0.0.rc1/lib/active_record/relation/query_methods.rb:1164:in `block (2 levels) in validate_order_args'
如何实现?
编辑 1
这是一个 accepted: true
:
[26] pry(main)> q.answers.first
=> #<Answer:0x007f997d7a5a80
id: 69,
body:
"public static Process CreateProcessAsUser(string filename, string args)\r\n {\r\n var hToken = WindowsIdentity.GetCurrent().Token;\r\n var hDupedToken = IntPtr.Zero;\r\n\r\n var pi = new PROCESS_INFORMATION();\r\n var sa = new SECURITY_ATTRIBUTES();\r\n sa.Length = Marshal.SizeOf(sa);\r\n\r\n try\r\n {\r\n if (!DuplicateTokenEx(\r\n hToken,\r\n GENERIC_ALL_ACCESS,\r\n ref sa,\r\n (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,\r\n (int)TOKEN_TYPE.TokenPrimary,\r\n ref hDupedToken\r\n ))\r\n throw new Win32Exception(Marshal.GetLastWin32Error());\r\n\r\n var si = new STARTUPINFO();\r\n si.cb = Marshal.SizeOf(si);\r\n ",
user_id: 1547,
question_id: 47,
created_at: Wed, 15 Jun 2016 05:20:11 UTC +00:00,
updated_at: Mon, 20 Jun 2016 22:34:08 UTC +00:00,
accepted: true,
language: nil,
comments_count: nil>
您需要将字符串传递给 order
方法:
q.answers.order("accepted = true DESC").order(:created_at)