Rails: # проверить, не отображается ли атрибут

#ruby-on-rails #ruby #ruby-on-rails-3

#ruby-on-rails #ruby #ruby-on-rails-3

Вопрос:

Я определяю его @foo как атрибут экземпляра класса и использую after_initialize обратный вызов для установки этого значения при создании / загрузке записи:

 class Blog < ActiveRecord::Base
  @foo = nil

  after_initialize :assign_value

  def assign_value
    @foo = 'bar'
  end
end
  

Однако, когда я inspect создаю объект Blog, я не вижу @foo атрибута:

  > Blog.first.inspect
=> "#<Blog id: 1, title: 'Test', created_at: nil, updated_at: nil>"
  

Что мне нужно сделать, чтобы inspect включить это? Или, наоборот, как inspect определить, что выводить?

Спасибо.

Ответ №1:

Активная запись определяет, какие атрибуты отображать в inspect, на основе столбцов в таблице базы данных:

 def inspect
  attributes_as_nice_string = self.class.column_names.collect { |name|
    if has_attribute?(name)
      "#{name}: #{attribute_for_inspect(name)}"
    end
  }.compact.join(", ")
  "#<#{self.class} #{attributes_as_nice_string}>"
end
  

Извлечено из base.rb на github

Чтобы изменить вывод inspect, вам придется перезаписать его своим собственным методом, например

 def inspect
  "#{super}, @foo = #{@foo}"
end
  

Который должен выводить:

 > Blog.first.inspect
=> "#<Blog id: 1, title: 'Test', created_at: nil, updated_at: nil>, @foo = 'bar'"
  

Комментарии:

1. Кроме того, я думаю, что вы не можете вызвать after_initialize с помощью символа ссылки на метод, вы должны явно создать метод с именем after_initialize (например, def after_initialize; @foo = 'bar'; end )

2. Переопределение было именно тем, что я в настоящее время пробовал с tryruby (черт, это проблема). Спасибо, что освободили меня от этого: D

3. Отлично, спасибо. Я понятия не имел, что Rails перезаписал метод Ruby inspect .