Open martinnicolas opened 1 month ago
hey, you can absolutely do this:
require 'shale'
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
hsh do
map 'first_name', to: :first_name, render_nil: true
map 'last_name', to: :last_name, render_nil: false
map 'age', to: :age, render_nil: true
end
end
puts Person.new(
first_name: nil,
last_name: nil,
age: nil
).to_hash(pretty: true)
# => {"first_name"=>nil, "age"=>nil}
Hi. thats nice! but is not the my case. I would try to explain a lit better.
require 'shale'
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
csv do
map 'first_name', to: :first_name, render_nil: true
map 'last_name', to: :last_name, render_nil: false
map 'age', to: :age, render_nil: true
end
end
puts Person.new(
first_name: nil,
last_name: nil,
age: nil
).to_hash
# => {}
I need the csv block because I'm importing a csv file. And I need to_hash for using https://github.com/zdennis/activerecord-import
to import content into my database. Could be possible to define another block for hsh? like this?
require 'shale'
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
csv do
map 'first_name', to: :first_name, render_nil: true
map 'last_name', to: :last_name, render_nil: false
map 'age', to: :age, render_nil: true
end
hsh do
map 'first_name', to: :first_name, render_nil: true
map 'last_name', to: :last_name, render_nil: false
map 'age', to: :age, render_nil: true
end
end
yes, you can define as many blocks as you want, this is valid:
require 'shale'
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
csv do
map 'first_name', to: :first_name, render_nil: true
map 'last_name', to: :last_name, render_nil: false
map 'age', to: :age, render_nil: true
end
hsh do
map 'first_name', to: :first_name, render_nil: true
map 'last_name', to: :last_name, render_nil: false
map 'age', to: :age, render_nil: true
end
json do
...
end
toml do
...
end
xml do
...
end
end
Nice! I was using this little hack. To prevent defining all maps again. But I think is better to redefine the mapping block for each format. Isnt it?
def to_hash
instance_variables.each_with_object({}) do |instance_variable_name, hash|
hash[instance_variable_name.to_s.delete("@")] = instance_variable_get(instance_variable_name)
end
end
Hi!. I notice that calling to_hash method on a Shale::Mapper object, nil values are not rendered. I can change this using https://www.shalerb.org/#rendering-nil-values
render_nil: true
but only for shale methodsto_json
,to_csv
etc. It could be a nice approach to implement something similar for to_hash. Thanks for your job!