Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add render_nil: true to change to_hash result #42

Open
martinnicolas opened this issue Jul 16, 2024 · 4 comments
Open

Add render_nil: true to change to_hash result #42

martinnicolas opened this issue Jul 16, 2024 · 4 comments

Comments

@martinnicolas
Copy link

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 methods to_json, to_csv etc. It could be a nice approach to implement something similar for to_hash. Thanks for your job!

@kgiszczak
Copy link
Owner

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}

@martinnicolas
Copy link
Author

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

@kgiszczak
Copy link
Owner

kgiszczak commented Jul 18, 2024

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

@martinnicolas
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants