管理工具中删除文件所有内容的方法

时间:2015-11-06 16:36:02

标签: ruby yaml

我创建了一个用户工具,允许论坛管理员在桌面上添加,编辑和删除用户,然后让他们能够将文件上传到他们的数据库中。我知道这应该直接用于数据库,但我正在制作它的人不希望我有权访问。

这是源代码:

#!/usr/bin/env ruby

require 'yaml'
require 'open-uri'

def menu
    print "Welcome to User Menu. Would you like to [A]dd users, [D]elete users, [E]dit users, [V]iew all users, or [Q]uit the system?\n"
    input = gets.chomp!
    case input
    when /a/i
        add_user
    when /d/i
        delete_user
    when /e/i
        edit_user
    when /v/i
        view_all
    else
        puts "Exiting system.."
        exit
    end
end

def add_user
    data = { username: prompt("Enter username:"), 
             email_address: prompt("Enter email:"), 
             member_status: prompt("Enter member status:") }
    File.open('users.yml', 'a') { |s| s.write(data.to_yaml) }
    add_user if restart
end

def delete_user
    hash = YAML.load_file('users.yml')
    delete_data = { username: prompt("Enter username:" ),
                    email_address: prompt("Enter email:" ),
                    member_status: prompt("Enter member status:" ) }
    File.open('users.yml', 'w'){ |f| f.dump(hash.to_yaml)}
end
#I literally want to punch a baby right now..

def edit_user
    #Still in process of creating
    edit_user if restart
end

def view_all
    content = URI('#left blank for security of site').read
end

def restart
    puts "Would you like to edit another user?"
    input = gets.chomp
    if input =~ /yes/i
        return true
    else
        puts "Exiting program.."
        exit
    end
end

def prompt ( message )
    puts message
    gets.chomp
end
menu

YAML文件示例:

---
:username: TEST
:email_address: TEST
:member_status: TEST
---
:username: TEST1
:email_address: TEST1
:member_status: TEST1

我在使用delete_user方法时遇到了一些麻烦。它删除文件的整个内容,或者根本不起作用。我尝试过多次重写:

def delete_user
    delete_data = { username: prompt("Enter username:") ,
                    email_address: prompt("Enter email:"),
                    member_status: prompt("Enter member status:") }
                    hash = YAML.load_file('users.yml')
                    hash.delete[username]
                    hash.delete[email_address]
                    hash.delete[status]
    File.open('users.yml', 'w'){ |f| f.dump(delete_data.to_yaml)}
end 
    #Found out why this one wasn't working due to me 
    #adding the wrong data to the hash
    #was also giving argument error.

我也试过取出File.open方面,这反过来说没有任何意义,但值得一试:

 def delete_user
    delete_data = { username: prompt("Enter username:") ,
                    email_address: prompt("Enter email:"),
                    member_status: prompt("Enter member status:") }
                    hash.delete[username]
                    hash.delete[email_address]
                    hash.delete[status]
     hash = YAML.load_file('users.yml', 'w') { |f| f.dump(delete_data.to_yaml) }
end
#Really doesn't make sense so I ended
#up using the following one

现在我有这个:

def delete_user
    hash = YAML.load_file('users.yml')
    delete_data = { username: prompt("Enter username:" ),
                    email_address: prompt("Enter email:" ),
                    member_status: prompt("Enter member status:" ) }
    File.open('users.yml', 'w'){ |f| f.dump(hash.to_yaml)}
end

我对接下来的尝试感到茫然。我用Google搜索了它,重写了它,等等。如何让delete_user只删除程序操作员给出的用户,而不是删除整个文件?

2 个答案:

答案 0 :(得分:1)

由于您传入的File.open('users.yml', 'w')参数,

users.yml将会打开w并开始在文件的开头写入数据。请参阅{{3 }}

您实际想要做的是搜索users.yml文件中的特定行并删除该文件中的该条目。

答案 1 :(得分:1)

考虑这些:

require 'yaml'

puts YAML.load(
'---
:username: TEST
:email_address: TEST
:member_status: TEST
---
:username: TEST1
:email_address: TEST1
:member_status: TEST1
'
)

# >> {:username=>"TEST", :email_address=>"TEST", :member_status=>"TEST"}

默认情况下,YAML仅加载单个文档。仅返回TEST(第一个文档)。删除文档标记:

require 'yaml'

puts YAML.load(
    '---
    :username: TEST
    :email_address: TEST
    :member_status: TEST
    :username: TEST1
    :email_address: TEST1
    :member_status: TEST1
    '
)
# >> {:username=>"TEST1", :email_address=>"TEST1", :member_status=>"TEST1"}

加载后,所有TEST1条目都在TEST条目上踩踏。

您可以使用其他方法加载数据:

require 'yaml'

users = YAML.load_stream(
'---
:username: TEST
:email_address: TEST
:member_status: TEST
---
:username: TEST1
:email_address: TEST1
:member_status: TEST1
'
)
users
# => [{:username=>"TEST", :email_address=>"TEST", :member_status=>"TEST"},
#     {:username=>"TEST1", :email_address=>"TEST1", :member_status=>"TEST1"}]

或者你需要一个不同的结构。

创建YAML时,我总是从Ruby或者我写的语言开始,然后用它来创建我的结构,然后让YAML序列化它,这样我就可以看到文件应该是什么样子了。使用往返代码的快速测试然后帮助我看到事情正常。

require 'yaml'

users = [
  {:username=>"TEST", :email_address=>"TEST", :member_status=>"TEST"},
  {:username=>"TEST1", :email_address=>"TEST1", :member_status=>"TEST1"}
]

puts users.to_yaml

# >> ---
# >> - :username: TEST
# >>   :email_address: TEST
# >>   :member_status: TEST
# >> - :username: TEST1
# >>   :email_address: TEST1
# >>   :member_status: TEST1

或者:

require 'yaml'

users = {
  'TEST' => {:email_address=>"TEST", :member_status=>"TEST"},
  'TEST1' => {:email_address=>"TEST1", :member_status=>"TEST1"}
}

puts users.to_yaml

# >> ---
# >> TEST:
# >>   :email_address: TEST
# >>   :member_status: TEST
# >> TEST1:
# >>   :email_address: TEST1
# >>   :member_status: TEST1

基本上,看起来你想要一个哈希数组或散列哈希值。第一个将强制主键是唯一的,而第二个可以允许重复。哪个更好?这是你决定的。

而且,为了说明现实,你需要能够管理两个完全独立的用户可以拥有相同名称的情况,因为有多个" John Smith"在世界上。这意味着使用一个跨用户唯一的密钥; email_address 可能是唯一的,但两个用户始终可以共享电子邮件地址,例如在小公司或同一家庭中。

注意:Ruby的YAML是建立在Psych之上的,这是定义load_fileload_stream的地方。试图在YAML文档中找到那些会导致沮丧。