2013-08-25 2 views
6

После получения всех значений из модели я хочу добавить другой пользовательский атрибут в класс ActiveRecord (этот атрибут не является столбцом в db), чтобы я мог использовать его в поле зрения, но рельсы не позволяйте мне добавить его. Что добавить в класс модели?Как добавить новый атрибут в ActiveRecord

@test.all 

@test.each do |elm| 
    elm[:newatt] = 'added string' 
end 

ошибка:

can't write unknown attribute `newatt' 
+0

Что вы хотите с этим делать? Только область или вы хотите сохранить ее в базе данных? – Mindbreaker

+0

Я не хочу сохранять его в базе данных. Я делаю некоторые обработки в каждом из них (см. Обновленный код), и я хочу добавить дополнительную информацию для каждого элемента. Он будет использоваться только в представлении. – Ladiko

+0

Возможный дубликат [Добавление дополнительных атрибутов времени выполнения для объекта activerecord] (http://stackoverflow.com/questions/7584592/adding-extra-run-time-attribs-to-an-activerecord-object) – mlt

ответ

4

Определить виртуальные атрибуты переменных экземпляра:

attr_accessor :newattr 
+0

Нет работа, см. обновленный код. – Ladiko

+2

'elm.newatt = 'добавлено string'' –

+0

Пожалуйста, просто сделайте так, как указывает Джесси в своем комментарии – boulder

8

попробовать это

class Test < ActiveRecord::Base 
    attr_accessor :newattr 
end 

вы можете получить доступ к нему, как

@test = Test.new 
@test.newattr = "value" 

Как вы можете заметить это свойство, а не хэш. поэтому он использует синтаксис .. Однако, если вам это нужно, чтобы вести себя как хэш вы можете сделать это без определения нового атрибута

@test.all 
@test.each do |elm| 
    new_elm = {} 
    new_elm[:newatt] = 'added string' 
end 

Наконец, я не совсем уверен, что вы пытаетесь сделать. если это не имеет смысла для вас, любезно перефразируйте свой вопрос, чтобы мы могли лучше понять проблему.

2

Я думаю, вы хотите назначить @test для запроса ActiveRecord, правильно? Попробуйте:

@test = MyARClass.select("*, NULL as newatt") 
@test.each {|t| t[:newatt] = some_value} 

Другим связанным с этим решением, чтобы сделать его метод одноэлементного класса, хотя вам придется прыгать, хотя обручи, чтобы сделать его доступным для записи, и я интуитивно чувствую, что это, вероятно, несет дополнительные издержки

@test = MyARClass.all 
@test.each do t 
    def t.newatt 
    some_value 
    end 
end 

Используя второй метод, вы, конечно, получите доступ к нему через @ test.first.newatt, а не @ test.first [: newatt]. Вы можете попробовать переопределить t. [] И t. [] =, Но это начинает становиться действительно грязным.

2

Если это действительно только временный и не должен быть в объекте:

@test.all 
@test_temp = [] 

@test.each do |elm| 
    @test_temp << {:elm => elm, :newatt => 'added string'} 
end 

В противном случае, есть также good answers here.

3

Если вы хотите это только для ваших взглядов и не имеют какой-либо другой цели, то вам не нужно, чтобы добавить attr_accessor

@test.all.select('tests.*, "added string" as newattr') 

здесь вы добавляете newattr атрибут для вывода запроса ActiveRecord со значением добавил строку '

1
@test.all 

@test.each do |elm| 
    write_attribute(:newatt, "added string") 
end 
0

Я встретил ту же проблему. и успешно обходить с помощью instance_eval

@test.all 

@test.each do |elm| 
    elm.instance_eval { @newatt = 'added string' } 
end 

Обычно он не запускается при использовании attr_accessor. он появляется, когда другие DSL переопределяют «newattr =», которые вызывают проблему. В моем случае это деньги-рельсы «монетизировать: newatt»

Явное использование write_attribute не работает, так как это является причиной увеличения исключения в рельсах 4.x

Смежные вопросы