Ruby on rails 为不带'attr\u访问器的rails模型设置非数据库属性`

Ruby on rails 为不带'attr\u访问器的rails模型设置非数据库属性`,ruby-on-rails,ruby,Ruby On Rails,Ruby,在PHP中,我可以为模型设置一个属性(不是数据库中的列)。例如(PHP代码) 但在rails中,当我设置数据库中不存在的任何属性时,它将抛出一个错误undefined method flag。有attr\u accessor方法,但是如果我需要大约十个临时属性,会发生什么呢?如果需要临时属性,可以将它们添加到singleton对象中 instance = Model.new class << instance attr_accessor :name end instance=

在PHP中,我可以为模型设置一个属性(不是数据库中的列)。例如(PHP代码)


但在rails中,当我设置数据库中不存在的任何属性时,它将抛出一个错误
undefined method flag
。有
attr\u accessor
方法,但是如果我需要大约十个临时属性,会发生什么呢?

如果需要临时属性,可以将它们添加到singleton对象中

instance = Model.new

class << instance
  attr_accessor :name
end
instance=Model.new

类attr_accessor所做的就是添加使用实例变量的getter和setter方法,例如

attr_accessor :flag
将添加以下方法:

def flag
  @flag
end

def flag=(val)
  @flag = val
end

如果您愿意,您可以自己编写这些方法,并让它们做一些比仅将值存储在实例变量中更有趣的事情(如果您愿意)。

这是意料之中的,因为ActiveRecord就是这样设计的。如果需要设置任意属性,则必须使用不同类型的对象

例如,Ruby提供了一个名为的库,它允许您创建可以分配任意键/值的对象。只有在需要保存到数据库时,才可以使用此类库,然后将对象转换为相应的ActiveRecord实例


不要试图将
ActiveRecord
建模为您刚才描述的行为,因为它根本就不是设计为以那种方式运行的。从你目前的PHP知识来看,这可能是一个错误。

正如这些家伙解释的那样,
attr\u accessor
只是一个快速的
setter
getter

例如,我们可以将记录初始化时的模型attr_访问器设置为一个,这样我们就可以更灵活地临时存储值()

比如:

class User < ActiveRecord::Base

  attr_accessor :vars

  after_initialize do |user|
    self.vars = Hash.new
  end

end
但是如果我需要大约十个临时属性,会发生什么呢


在对象中具有非列属性是一种代码味道,至少对我来说是这样。这里有一些相关内容:您通常不会在rails中使用$-变量。你把php和ruby代码混合在一起了吗?@MaxWilliams不,这是一个php示例。哦,那么你是说“我如何在rails中做到这一点?”?至少对我来说,这还不清楚。@MaxWilliams噢,我很抱歉,因为让这个例子不清楚。非常感谢,直到你告诉我,我才知道
OpenStruct
lib。我将您的解决方案与@Nimir solution结合在一起,它工作得非常完美:D
attr\u accessor:flag在初始化do | user | self.flag=OpenStruct.new end
之后,我可以使用
@user.flag.hello=“hello World”
ps:sr,我不知道如何格式化代码
class User < ActiveRecord::Base

  attr_accessor :vars

  after_initialize do |user|
    self.vars = Hash.new
  end

end
user = User.new

#set
user.vars['flag'] = true

#get
user.vars['flag']
#> true
#app/models/user.rb
class User < ActiveRecord::Base
   attr_accessor :flag, :other_attribute, :other_attribute2, :etc...
end
#app/models/user.rb
class User < ActiveRecord::Base
   attr_accessor :flag

   # getter
   def flag
     @flag
   end

   # setter
   def flag=(val)
     @flag = val
   end
end