简体   繁体   English

在Ruby中使用和编辑类变量?

[英]Using and Editing Class Variables in Ruby?

So I've done a couple of days worth of research on the matter, and the general consensus is that there isn't one. 因此,我已经就此事进行了为期两天的研究,并且普遍的共识是没有一个。 So I was hoping for an answer more specific to my situation... 所以我希望能得到一个更具体的答案……

I'm using Rails to import a file into a database. 我正在使用Rails将文件导入数据库。 Everything is working regarding the import, but I'm wanting to give the database itself an attribute, not just every entry. 一切都与导入有关,但是我想给数据库本身一个属性,而不仅仅是每个条目。 I'm creating a hash of the file, and I figured it'd be easiest to just assign it to the database (or the class). 我正在创建文件的哈希,我认为将其分配给数据库(或类)是最简单的。

I've created a class called Issue (and thus an 'issues' database) with each entry having a couple of attributes. 我创建了一个名为Issue的类(因此是一个“问题”数据库),每个条目都有几个属性。 I was wanting to figure out a way to add a class variable (at least, that's what I think is the best option) to Issue to simply store the hash. 我想找到一种向Issue添加类变量(至少是我认为的最佳选择)的方法,以简单地存储哈希。 I've written a rake to import the file, iff the new file is different than the previous file imported (read, if the hash's are different). 如果新文件与先前导入的文件不同(如果散列不同,请阅读),我已经写了一篇耙子来导入文件。

desc "Parses a CSV file into the 'issues' database"
task :issues, [:file] => :environment do |t, args|
  md5 = Digest::MD5.hexdigest(args[:file])
  puts "1: Issue.md5 = #{Issue.md5}"

  if md5 != Issue.md5
    Issue.destroy_all()
    #import new csv file
    CSV.foreach(args[:file]) do |row|

      issue = {
        #various attributes to be columns...
        }
      Issue.create(issue)
   end #end foreach loop
  Issue.md5 = md5
  puts "2: Issue.md5 = #{Issue.md5}"
  end #end if statement
end #end task

And my model is as follows: 我的模型如下:

class Issue < ActiveRecord::Base

  attr_accessible :md5

  @@md5 = 5

  def self.md5
    @@md5
  end

  def self.md5=(newmd5)
    @@md5 = newmd5
  end

  attr_accessible #various database-entry attributes
end

I've tried various different ways to write my model, but it all comes down to this. 我尝试了各种不同的方式来编写模型,但这全都归结于此。 Whatever I set the @@md5 in my model, becomes a permanent change, almost like a constant. 无论我在模型中设置@@ md5多少,都将变成永久更改,几乎就像一个常量。 If I change this value here, and refresh my database, the change is noted immediately. 如果我在此处更改此值并刷新数据库,则会立即记录该更改。 If I go into rails console and do: 如果我进入Rails控制台并执行以下操作:

Issue.md5        # => 5
Issue.md5 = 123  # => 123
Issue.md5        # => 123

But this change isn't committed to anything. 但是这种改变并没有实现。 As soon as I exit the console, things return to "5" again. 退出控制台后,事情又回到“ 5”。 It's almost like I need a .save method for my class. 几乎就像我的班级需要一个.save方法。

Also, in the rake file, you see I have two print statements, printing out Issue.md5 before and after the parse. 另外,在rake文件中,您看到我有两个打印语句,分别在解析前后打印出Issue.md5。 The first prints out "5" and the second prints out the new, correct hash. 第一个打印出“ 5”,第二个打印出正确的新哈希。 So Ruby is recognizing the fact that I'm changing this variable, it's just never saved anywhere. 因此Ruby意识到我正在更改此变量,但它从未保存在任何地方。

Ruby 1.9.3, Rails 3.2.6, SQLite3 3.6.20. Ruby 1.9.3,Rails 3.2.6,SQLite3 3.6.20。

tl;dr I need a way to create a class variable, and be able to access it, modify it, and re-store it. tl; dr我需要一种创建类变量的方法,并能够访问,修改和重新存储它。

Fixes please? 修复好吗? Thanks! 谢谢!

There are a couple solutions here. 这里有一对夫妇的解决方案。 Essentially, you need to persist that one variable: Postgres provides a key/value store in the database, which would be most ideal, but you're using SQLite so that isn't an option for you. 本质上,您需要保留一个变量:Postgres在数据库中提供键/值存储,这是最理想的,但是您使用的是SQLite,因此这不是您的选择。 Instead, you'll probably need to use either redis or memcached to persist this information into your database. 相反,您可能需要使用redismemcached将这些信息持久保存到数据库中。

Either one allows you to persist values into a schema-less datastore and query them again later. 任一种都可以使您将值持久存储到无模式的数据存储中,并在以后再次查询它们。 Redis has the advantage of being saved to disk, so if the server craps out on you you can get the value of md5 again when it restarts. Redis具有保存到磁盘的优势,因此,如果服务器无法正常运行,则重新启动时可以再次获得md5的值。 Data saved into memcached is never persisted, so if the memcached instance goes away, when it comes back md5 will be 5 once again. 保存到memcached中的数据永远不会持久保存,因此,如果memcached实例消失了,那么当它返回时,md5将再次为5。

Both redis and memcached enjoy a lot of support in the Ruby community. redismemcached都在Ruby社区中获得了很多支持。 It will complicate your stack slightly installing one, but I think it's the best solution available to you. 这会使您的堆栈稍微复杂一点,但只需安装一个即可,但是我认为这是为您提供的最佳解决方案。 That said, if you just can't use either one, you could also write the value of md5 to a temporary file on your server and access it again later. 就是说,如果您不能使用任何一个,也可以将md5的值写入服务器上的一个临时文件,然后稍后再次访问它。 The issue there is that the value then won't be shared among all your server processes. 那里的问题是,该值将不会在所有服务器进程之间共享。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM