[英]Ruby with Sequel and Sinatra: form parameter passing
我是Ruby和Sinatra的新手。 我正在嘗試通過HTML表單傳遞參數,並將它們插入到帶有Sequel的PostgreSQL數據庫(在Heroku中)中。
與數據庫的連接有效,因為我已成功使用此代碼塊
DB = Sequel.connect(connection_ credentials)
insert_ds = DB["INSERT INTO users (email_address, username, password) VALUES ('email@email.com', 'my_username', 'my_password')"]
insert_ds.insert
這工作正常,但我無法從HTML表單插入數據。 數據未傳遞。
因此,例如,這不起作用
@email_address = params[:email_address]
@username = params[:username]
@password = params[:password]
insert_ds = DB["INSERT INTO users (email_address, username, password) VALUES (@email_address, @username', @password)"]
insert_ds.insert
錯誤消息是
/ PG :: Error處的Sequel :: DatabaseError:錯誤:列“ email_address”不存在LINE 1:... sers(電子郵件地址,用戶名,密碼)值(@email_addr ... ^
這導致我推測該參數未傳遞
完整的代碼是:
require 'sinatra'
require "rubygems"
require "sequel"
require 'sinatra/sequel'
require 'pg'
DB = Sequel.connect('postgres://my username:my password@ec2-54-243-250-125.compute-1.amazonaws.com:5432/d70h0792oqobc')
get '/' do
#@users = users.all :order => :id.desc
#@title = 'All Users'
erb :index
end
post '/' do
@email_address = params[:email_address]
@username = params[:username]
@password = params[:password]
insert_ds = DB["INSERT INTO users (email_address, username, password) VALUES (@email_address, @username, @password)"]
insert_ds.insert
redirect '/'
end
__END__
@@ layout
<!DOCTYPE html>
<html>
<head></head>
<body>
<%= yield %>
</body>
</html>
@@index
<section id="add">
<form action="/" method="post">
<label class="label"> <span>Email Address: </span> </label> <input type="text" id="email_address" name="email_address" />
<label class="label"> <span>Username: </span> </label> <input type="text" id="username" name="username" />
<label class="label"> <span>Password: </span> </label> <input type="password" id="password" name="password" />
<input type="submit" value="Register me!">
</form>
</section>
非常感謝所有幫助!
謝謝。
簡介 :由於對Sequel的工作方式(以及Ruby的字符串插值的工作方式)有誤解,您的代碼無法正常工作是因為您向數據庫發送了無效的SQL。
詳細信息 :使用Sequel庫時,幾乎不需要(也不需要)編寫原始SQL代碼。 若要更適當地使用Sequel,請執行以下操作:
DB[:users] << {
email_address: params[:email_address],
username: params[:my_username],
password: params[:my_password]
}
或這個:
DB[:users].insert( email_address:params[:email_address], … )
如果您出於某種原因想要將它們存儲為實例變量(您正在帖子的視圖響應中使用它們?),則:
@email = params[:email_address]
@user = params[:username]
@pass = params[:password]
DB[:users] << { email_address:@email, username:@user, password:@pass }
如果您確實想編寫原始SQL,則可以安全地使用占位符,如下所示:
DB[
'INSERT INTO users (email_address,username,password) VALUES (?,?,?)',
params[:email_address],
params[:username],
params[:password],
]
這樣做的好處是可以防止用戶在您的站點上執行SQL注入攻擊 ,例如說用戶名是bob','haha'); drop table users; select('
bob','haha'); drop table users; select('
bob','haha'); drop table users; select('
。 (想想如果將其放入兩個'
字符之間的普通INSERT
語句中會發生什么。)
由於您的表單參數與列名匹配,因此您甚至可以使用自定義函數對哈希進行切片,以使其變得更加容易,例如
DB[:users] << params.slice(:email_address,:username,:password)
閱讀續集文檔 (例如備忘單 )以獲取有關如何正確使用它的更多信息。
為了未來 :
您的問題與Sinatra或參數無關,而僅僅是您如何錯誤地使用Sequel。 為了將來測試要獲取的參數,可以執行以下操作:
p params
並查看您的控制台(假設您正在本地開發?),或者如果您正在服務器上實時開發(* shudder *),則使用Heroku提供的任何日志記錄功能。 另外,您甚至可以執行以下操作:
post '/' do
params.inspect
end
當您發布表單時,您將看到params
哈希中的確切內容。 這樣一來,您就不會對錯誤的地區進行指責和調查。
您正在嘗試對全局變量@username
@email_address
, @username
@email_address
和@password
進行插值,但尚未使用插值運算符#
您的SQL字符串顯示為
INSERT INTO users (email_address, username, password) VALUES (@email_address, @username', @password)
何時(除了流浪單引號之外),您的意思是使這些變量的值出現在命令中。 你應該寫
insert_ds = DB["INSERT INTO users (email_address, username, password)
VALUES (#@email_address, #@username, #@password)"]
通過添加很容易診斷
puts insert_ds
分配后直接進行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.