如何在控制台中按字母顺序显示Rails ActiveRecord字段

时间:2018-10-11 22:47:02

标签: ruby-on-rails ruby activerecord

找不到此配置或设置(已经用Google搜索了好几次)。在Rails控制台中检查某些模型对象时,为什么有时按字母顺序显示模型字段,而在其他部署中却大多数时候却不显示?

示例:

### FIELDS NOT SORTED
#rails console
(main)> l = Loan.find '123' 
 => #<Loan:0x000000066722e8
 id: "8f196106c00e",
 user_id: "f90084a53972",
 borrower_id: "043bb77b3aac",
 parent_id: nil,
 score_id: "f00c39e74570",
 number: 11231321,
 scoring_tag: nil,
 .....

但是在其他部署中,当我进入Rails控制台

 # FIELDS SORTED ALPHABETICALLY
 (main)> l = Loan.find '123'
  => #<Loan:0x007fca8b45a468
  active_servicer_id: nil,
  amortization: nil,
  amount: 150000.0 (BigDecimal),
  application_fee: nil,
  borrower_id: "asdasdajdjasd",
  borrower_requested_closing_attorney: nil,
  channel: nil,
  closed_date: nil,
  commitment_end_at: nil,

如何使Rails控制台显示已排序模型的输出?比较两个记录有时有时是必需的。

2 个答案:

答案 0 :(得分:1)

如果只想打印出属性,则可以更明确地做到这一点:

Loan.find(123).attributes.sort_by(&:first).to_h

如果您确实希望控制台打印能够执行此操作,则可能需要覆盖inspect方法。至少对于irb和其他一些控制台,这是确定打印内容的方法。如果控制台还使用其他插件或gem,则可能必须查看文档以找到适当的方法。

类似的内容(根据需要进行修改,例如,以更好地模仿默认的inspect,显示object_id等)

class Loan ...
  def inspect
    (self.class.name + ": " + attributes.sort_by(&:first).to_h).to_s
  end
end

答案 1 :(得分:0)

在Ruby的Hash中,其元素的顺序是任意的。当进行检查 -ed时(如在rails控制台的输出中),方法inspect仅使用each_pair或类似的东西,因此顺序可以是任意的。实际上,Hash#each_pair的顺序通常似乎遵循每个哈希元素创建的顺序。但是不能保证!另外,Rails(或ActiveRecord)如何创建这些实例是另一个问题(我想您所看到的字母顺序起源于Rails是如何创建它们的;它可能与它们在数据库中的存储方式有关)。总之,只要使用哈希,就无法控制它们的存储方式。但是您可以调整它们的检查版本。

以下策略是为其所有子类重新定义ApplicationRecord#inspect,以便修改任何Models的inspect方法,但不修改任何其他类。

将以下代码放入app/目录中的任何文件(例如 ,明显的文件名为/app/models/application_record.rb):

class ApplicationRecord
  alias_method :inspect_orig, :inspect if ! self.method_defined?(:inspect_orig)
  def inspect
    klass = self.class 
    if klass == ApplicationRecord
      return inspect_orig
    end
    attr_list = attribute_names.sort.map { |name| "#{name}: "+attributes[name].inspect }.join ', '
    sprintf('<%s:0x%s %s>', klass.name, object_id.to_s(16), attr_list)
  end
end

或者,如果您只想在会话期间临时激活rails console,则可以在每次打开ApplicationRecord时运行它。

请注意,ApplicationRecord的父类的名称可以按以下方式添加(在Rails 5.2中;但是我认为对于类{{1} }应该在读取文件之前定义。)

class ApplicationRecord < ActiveRecord::Base

我注意到您的Rails控制台输出看起来与Rails 5.2.1略有不同,这可能是由于版本(?)的不同所致。在上面的代码片段中,我试图模仿您似乎获得的输出。无论如何都要根据自己的喜好进行调整;现在您可以完全控制它了!

EDIT1
上面的描述适用于Rails5。在Rails 4中,类名称应为

class ActiveRecord::Base

EDIT2
在上面的代码段中,它显示#object_id n.b。,在Rails 5.2中未显示)。但是,#inspect为对象实例显示的内容与#object_id不同,如this answer中详细说明。如果您希望显示它,可以采用以下方法(左侧值为sprintf的格式):

'0x%016x' % (object_id << 1)