简体   繁体   中英

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. 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. 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. 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. If I change this value here, and refresh my database, the change is noted immediately. If I go into rails console and do:

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. It's almost like I need a .save method for my class.

Also, in the rake file, you see I have two print statements, printing out Issue.md5 before and after the parse. The first prints out "5" and the second prints out the new, correct hash. So Ruby is recognizing the fact that I'm changing this variable, it's just never saved anywhere.

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.

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. Instead, you'll probably need to use either redis or memcached to persist this information into your database.

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. Data saved into memcached is never persisted, so if the memcached instance goes away, when it comes back md5 will be 5 once again.

Both redis and memcached enjoy a lot of support in the Ruby community. 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. The issue there is that the value then won't be shared among all your server processes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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