简体   繁体   中英

How to map hash keys to methods for an encapsulated Ruby class (tableless model)?

I am using Ruby on Rails 3 and I am tryng to map a hash ( key , value pairs) to an encapsulated Ruby class (tableless model) making the hash key as a class method that returns the value .

In the model file I have

class Users::Account #< ActiveRecord::Base
  def initialize(attributes = {})
    @id        = attributes[:id]
    @firstname = attributes[:firstname]
    @lastname  = attributes[:lastname]
  end
end

def self.to_model(account)
  JSON.parse(account)
end

My hash is

hash = {\"id\":2,\"firstname\":\"Name_test\",\"lastname\":\"Surname_test\"}

I can make

account = Users::Account.to_model(hash)

that returns (debugging)

--- 
id: 2
firstname: Name_test
lastname: Surname_test

That works, but if I do

account.id

I get this error

NoMethodError in Users/accountsController#new    
undefined method `id' for #<Hash:0x00000104cda410>

I think because <Hash:0x00000104cda410> is an hash (!) and not the class itself. Also I think that doing account = Users::Account.to_model(hash) is not the right approach.

What is wrong? How can I "map" those hash keys to class methods?

It would look better if you were to rewrite it like this

account = Users::Account.from_json(json)

and down there

def self.from_json(json_str)
   new(JSON.parse(json_str))
end

There is also a "block initializer" that I often use for initializing from a hash https://github.com/guerilla-di/tracksperanto/blob/master/lib/tracksperanto/block_init.rb so if you were to use that you could transform your class definition to

class Users::Account
  include BlockInit
  attr_accessor :id, :firstname, :lastname
  def self.from_json(json_str)
    new(JSON.parse(json_str))
  end
end

You have not initailized the class with the hash. You should do:

json = "{\"id\":2,\"firstname\":\"Name_test\",\"lastname\":\"Surname_test\"}"
hash = Users::Account.to_model(json)
account = Users::Account.new(hash)

Then account.id will give the value.

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