我创建了一个用户工具,允许论坛管理员在桌面上添加,编辑和删除用户,然后让他们能够将文件上传到他们的数据库中。我知道这应该直接用于数据库,但我正在制作它的人不希望我有权访问。
这是源代码:
#!/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
只删除程序操作员给出的用户,而不是删除整个文件?
答案 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_file
和load_stream
的地方。试图在YAML文档中找到那些会导致沮丧。