ActiveRecord虚拟属性作为记录属性处理

时间:2009-10-13 21:50:07

标签: ruby-on-rails activerecord

我遇到的问题是to_json没有呈现我的虚拟属性

class Location < ActiveRecord::Base
    belongs_to :event
    before_create :generate_oid
    validates_associated :event

    attr_accessor :event_oid

    def event_oid
      @event_oid = event.oid
    end
end

event_oid不是由:

返回的数组的一部分
Location.first.attributes

当使用to_json自动将记录属性序列化为jason时,这对我来说尤其成问题。 to_json省略了我的虚拟属性。

如何将虚拟属性视为实际实例属性?

编辑:

to_json只是将我的虚拟属性视为实际属性的方法的一个示例。

6 个答案:

答案 0 :(得分:5)

您想要修改属性哈希。这里有一些额外的代码,以确保您关心的属性已准备好与to_json一起使用或另一种依赖于对象加载属性的方法。

class Location < ActiveRecord::Base
    belongs_to :event
    before_create :generate_oid
    validates_associated :event

    after_save :event_oid

    attr_accessor :event_oid

    def event_oid
      @event_oid = @attributes["event_oid"] = event.oid if event.nil?
    end       

    def after_initialize
      event_oid
    end


end

to_json以及许多基于对象属性生成事物列表的其他方法。在使用数据库表和名称进行对象初始化时会填充哪个,遗憾的是实例变量不会更新此哈希值。

P.S。如果你想以这种方式使用许多属性,这不是很干。您可以使用符号数组,确定性方法名称和class_eval块一次将此过程应用于多个符号。

警告

我们在这里弄乱了rails内部。没有人知道它会如何导致其他事情失败。我还没有测试过save和to_json,当属性hash包含不是列名的键时,两者都有效。因此,使用它需要您自担风险。

答案 1 :(得分:2)

to_json(:methods => [:event_oid])怎么样,这有用吗?

答案 2 :(得分:2)

然后自己实施#to_json:

class Location < ActiveRecord::Base
  def to_json(options={})
    options[:methods] ||= []
    options[:methods] << :event_oid
    super(options)
  end
end

答案 3 :(得分:0)

我尝试François Beausoleil's answer并在将to_json修改为as_json

之后将其付诸实践
def as_json(options={})
  options[:methods] ||= []
  options[:methods] << :class_to_s
  super(options)
end

答案 4 :(得分:0)

location.to_json(:methods => :event_oid)

如此处所述:http://apidock.com/rails/ActiveRecord/Serialization/to_json

在控制器中,只需使用:

format.json { render json: @location.to_json(:methods => :event_oid) }

答案 5 :(得分:0)

一个古老的问题,但是一旦您知道怎么做,OP所要问的事情就变得可能和简单。 这里是一个完整的可运行示例,但您需要的所有内容都在Location类中。 after_initialize语句扩展了模型的属性,require 'active_record' ActiveRecord::Base.establish_connection( :adapter=> "sqlite3", :database=> ":memory:" ) ActiveRecord::Schema.define do create_table :events do |table| table.column :name, :string end create_table :locations do |table| table.column :name, :string table.column :event_id, :integer end end class Event < ActiveRecord::Base has_one :location end class Location < ActiveRecord::Base belongs_to :event attribute :event_name, :string after_initialize do self.event_name = event.name end end Event.create(name: 'Event1') Location.create(name: 'Location1', event_id: 1) p Model.attribute_names p Event.first p Event.first.location #["id", "name", "event_id", "event_name"] #<Event id: 1, name: "Event1"> #<Location id: 1, name: "Location1", event_id: 1, event_name: "Event1"> 负责值的分配。

df1 = pd.read_csv('DataSources/file_today.csv')
df2 = pd.read_csv('DataSources/file_tomorrow.csv')

df = pd.concat([df1, df2])

df = df.sort_values(['MacAddress','Date'])
new_df = df.drop_duplicates(['MacAddress'], keep ='first')

drop_df = df.merge(new_df, how = 'outer' ,indicator=True).loc[lambda x : x['_merge']=='left_only']

# your result
drop_df