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

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

这是源代码:

#!/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只删除程序操作员给出的用户,而不是删除整个文件?

考虑这些:

 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_streamload_stream地方。 试图在YAML文档中找到那些会导致沮丧。

File.open('users.yml', 'w')将打开users.yml并开始在文件的开头写入数据,因为您传入了w参数。请参阅文档 。

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