Rails 3 добавляет виртуальный атрибут динамически - PullRequest
9 голосов
/ 02 сентября 2011

Мои настройки: Rails 3.0.9, Ruby 1.9.2

У меня есть причины для этого, но мне нужен способ динамического добавления виртуального атрибута в набор результатов activerecord. Это означает, что я не использую attr_accessor в модели и вместо этого хочу динамически добавлять виртуальные атрибуты в набор результатов.

Например,

users = User.all
#a user has following attributes: name, email, password

Что мне нравится делать - это добавить (без использования attr_accessor) виртуальный атрибут status к users, это возможно?

Ответы [ 4 ]

15 голосов
/ 02 сентября 2011

Вы должны сделать это:

users.each do |user|
  user.instance_eval do
    def status
      instance_variable_get("@status")
    end        
    def status=(val) 
      instance_variable_set("@status",val)
    end
  end
end
2 голосов
/ 02 сентября 2011

вы можете сделать следующее:

добавьте атрибут «extras», который будет доступен как Hash, и который будет хранить любые дополнительные / динамические атрибуты, а затем скажите Rails, чтобы он сохранял этот Hash через JSON в ActiveRecord, Mongo или любом другом используемом вами

например:.

class AddExtrasToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :extras, :text    # do not use a binary type here! (rails bug)
  end
  ...
end

затем в модели добавьте оператор для «сериализации» этого нового атрибута - например, это означает, что он сохраняется как JSON

class User < ActiveRecord::Base
...
serialize :extras
...
end

Теперь вы можете сделать это:

   u = User.find 3

   u.extras[:status] = 'valid'
   u.save

Вы также можете добавить немного магии в модель User, чтобы посмотреть на дополнительные функции Hash, если получит вызов метода method_missing ()

Смотрите также: Google "Rails 3 serialize"

1 голос
/ 17 мая 2016

Вы можете просто сделать:

users.each { |user| user.class_eval { attr_accessor :status } }

Все users будут иметь user.status и user.status = :new_status.

1 голос
/ 22 апреля 2012

Если ваши атрибуты доступны только для чтения, вы также можете добавить их, выбрав их в запросе к базе данных.Поля, которые появляются в результате SQL-результата, будут автоматически добавлены как атрибуты.

Примеры:

User.find_by_sql('users.*, (...) AS status')
User.select('users.*, joined_table.status').join(...)

В этих примерах у вас будут все атрибуты User и дополнительные statusатрибут.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...