0
votes

I have a simple sinatra app uses yaml files to handle data. One of the feature is an User can vote or veto for a Question. The vote feature works fine, but I met some weird things when implementing the veto feature.

Briefly saying:

  • when a question's current votes_count is positive (>= 1), the number will decrease correctly
  • but when a question's current votes_count is zero or negative, the number will successfully decrease in the data hash, but after dump data hash into the yaml file, negative becomes positive.

This is the yaml file for Question:

'1': !ruby/hash:Sinatra::IndifferentHash
  title: " Best way to require all files from a directory in ruby?"
  description: What's the best way to require all files from a directory in ruby ?
  user_id: '3'
  votes_count: 0

# other user information

This is the route handler relates to veto feature:

post "/questions/:id/veto" do
  check_vote_validity_for_question(params[:id])
  @question = Question.find_by(:id, params[:id])
  @question.votes_count = (@question.votes_count.to_i - 1)
  Question.update(params[:id], votes_count: @question.votes_count )
  # omit user related code
end

This is the update method:

  def self.update(id, attrs)
    data = load_data_of(data_name)
    # binding.pry
    obj_info = data[id]
    attrs.each do |k, v|
      v = v.to_s if v.is_a?(Array)
      obj_info[k] = v
    end
    # binding.pry
    File.open(File.join(data_path, "#{data_name.to_s}.yaml"), "w+") do |f|
      f.write(Psych.dump(data).delete("---"))
    end
  end

If I pause the program inside update method before and after update the data hash, it shows the value of votes_count was set correctly.

Before:

[1] pry(Question)> data
=> {"1"=>
  {"title"=>" Best way to require all files from a directory in ruby?",
   "description"=>"What's the best way to require all files from a directory in ruby ?",
   "user_id"=>"3",
   "votes_count"=>0},

After:

[1] pry(Question)> data
=> {"1"=>
  {"title"=>" Best way to require all files from a directory in ruby?",
   "description"=>"What's the best way to require all files from a directory in ruby ?",
   "user_id"=>"3",
   "votes_count"=>-1},

The value of the key"votes_count" in data hash is -1 after updating, but after I dumping the data hash into yaml file, the value of "votes_count" of the user in the yaml file became 1. And if the value in hash is -2, it will become 2 in the yaml file.

I tried making a hash which has a negative value in irb, then dump it into a yaml file, things work ok. I have no idea what happened. Could anybody help me?

1
"it became 1", what does it refer to? Does that mean the hash you indicate in the sentence fragment before that became one? Or the value for votes_count? Or the key votes_count changed into the number 1? Or the YAML file contains 1 as value for the key vote_count? Nowhere in your code "votes_count" is a value, it is a key. Please edit your question to make it less ambiguous. - Anthon
@Anthon, I edited the question. If I have a hash like h = { "a" => -2 }, then after I dumping h into a yaml file, the content in yaml file becomes a: 2 - Xullnn

1 Answers

5
votes

It looks the problem in the line

f.write(Psych.dump(data).delete("---"))

You delete -.

For example

"-1".delete("---") #=> "1"