Как отобразить поля Rails ActiveRecord в алфавитном порядке в консоли - PullRequest
0 голосов
/ 12 октября 2018

Не могу найти конфигурацию или настройку для этого (уже несколько раз гуглил).При проверке некоторых объектов модели в консоли 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,
 .....

, но в другихразвертывания, когда я захожу в консоль рельсов

 # 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,

Как я могу заставить рельсы консоль отображать вывод отсортированных моделей?Это иногда необходимо при сравнении двух записей.

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

В Ruby's Hash порядок его элементов произвольный.Когда он проверяет -ed (как в выводе консоли rails), метод inspect просто использует each_pair или что-то подобное, и поэтому порядок может быть произвольным.На практике порядок для Hash#each_pair обычно соответствует порядку, в котором создается каждый элемент Hash;однако нет никакой гарантии!Кроме того, то, как Rails (или ActiveRecord) создает эти экземпляры, является другой проблемой (я предполагаю, что алфавитный порядок, который вы видите, возникает из-за того, как Rails их создал; это может иметь отношение к тому, как они хранятся в БД).В любом случае, суть в том, что вы не можете контролировать, как они хранятся, пока используется хэш.Но вы можете настроить, как они проверяют -ед.

Следующая стратегия состоит в том, чтобы переопределить ApplicationRecord#inspect для любого из его дочерних классов, чтобы метод 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 может быть добавлено какследует (в случае Rails 5.2; но я не думаю, что включение родительского класса является обязательным, поскольку класс ApplicationRecord должен быть определен до чтения файла).

class ApplicationRecord < ActiveRecord::Base

Я замечаювыходные данные вашей консоли rails выглядят немного иначе, чем мои Rails 5.2.1, возможно, из-за разницы в версиях (?).В приведенном выше фрагменте кода я попытался имитировать результаты, которые вы, похоже, получили.В любом случае настройте его по своему вкусу;теперь у вас есть полный контроль над ним!

EDIT1 :
Вышеприведенное описание относится к Rails 5. В Rails 4 имя класса должно быть

class ActiveRecord::Base

EDIT2 :
В приведенном выше фрагменте кода показано #object_id ( nb , оно не отображается в Rails 5.2).Однако то, что #inspect показывает для экземпляров Object, отличается от #object_id, как подробно объяснено в этого ответа .Если вы предпочитаете отображать его, используйте следующий способ (значение в левой части - это формат sprintf):

'0x%016x' % (object_id << 1)
0 голосов
/ 12 октября 2018

Если вы просто хотите распечатать атрибуты, вы можете сделать это более явно:

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

Если вы действительно хотите, чтобы консольная печать выполняла это, вы можетепереопределить метод inspect.По крайней мере, для irb и некоторых других консолей, это метод, который определяет, что будет напечатано.Если у вас есть какой-то другой плагин или гем, который использует консоль, вам, возможно, придется взглянуть на документы, чтобы найти подходящий метод.

Что-то вроде (измените по своему желанию, например, чтобы лучше имитировать значение по умолчанию inspect, дисплей object_id и т. д.)

class Loan ...
  def inspect
    (self.class.name + ": " + attributes.sort_by(&:first).to_h).to_s
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...