PG::SyntaxError 在 /bookmarks - 我无法弄清楚为什么 SQL 查询是错误的
PG::SyntaxError at /bookmarks - I'm unable to work out why the SQL query is wrong
当 运行 我的应用程序使用 sinatra 时,我收到错误消息 PG::SyntaxError at /bookmarks
ERROR: syntax error at or near "{" LINE 1: SELECT * FROM users WHERE id = {:id=>"5"} ^
当我单击 /users/new
路线上的提交按钮时会发生这种情况,然后我应该将我带到索引路线 /
.
回溯提供以下信息
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/database_connection.rb in async_exec
@connection.exec(sql)
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/database_connection.rb in query
@connection.exec(sql)
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/user.rb in find
result = DatabaseConnection.query("SELECT * FROM users WHERE id = #{id}")
app.rb in block in <class:BookmarkManager>
@user = User.find(id: session[:user_id])
这是 database_connection 文件
require 'pg'
class DatabaseConnection
def self.setup(dbname)
@connection = PG.connect(dbname: dbname)
end
def self.connection
@connection
end
def self.query(sql)
@connection.exec(sql)
end
end
这是用户模型
require_relative './database_connection'
require 'bcrypt'
class User
def self.create(email:, password:)
encypted_password = BCrypt::Password.create(password
)
result = DatabaseConnection.query("INSERT INTO users (email, password) VALUES('#{email}', '#{encypted_password}') RETURNING id, email;")
User.new(id: result[0]['id'], email: result[0]['email'])
end
attr_reader :id, :email
def initialize(id:, email:)
@id = id
@email = email
end
def self.find(id)
return nil unless id
result = DatabaseConnection.query("SELECT * FROM users WHERE id = #{id}")
User.new(
id: result[0]['id'],
email: result[0]['email'])
end
end
这是控制器
require 'sinatra/base'
require './lib/bookmark'
require './lib/user'
require './database_connection_setup.rb'
require 'uri'
require 'sinatra/flash'
require_relative './lib/tag'
require_relative './lib/bookmark_tag'
class BookmarkManager < Sinatra::Base
enable :sessions, :method_override
register Sinatra::Flash
get '/' do
"Bookmark Manager"
end
get '/bookmarks' do
@user = User.find(id: session[:user_id])
@bookmarks = Bookmark.all
erb :'bookmarks/index'
end
post '/bookmarks' do
flash[:notice] = "You must submit a valid URL" unless Bookmark.create(url: params[:url], title: params[:title])
redirect '/bookmarks'
end
get '/bookmarks/new' do
erb :'bookmarks/new'
end
delete '/bookmarks/:id' do
Bookmark.delete(id: params[:id])
redirect '/bookmarks'
end
patch '/bookmarks/:id' do
Bookmark.update(id: params[:id], title: params[:title], url: params[:url])
redirect('/bookmarks')
end
get '/bookmarks/:id/edit' do
@bookmark = Bookmark.find(id: params[:id])
erb :'bookmarks/edit'
end
get '/bookmarks/:id/comments/new' do
@bookmark_id = params[:id]
erb :'comments/new'
end
post '/bookmarks/:id/comments' do
Comment.create(text: params[:comment], bookmark_id: params[:id])
redirect '/bookmarks'
end
get '/bookmarks/:id/tags/new' do
@bookmark_id = params[:id]
erb :'/tags/new'
end
post '/bookmarks:id/tags' do
tag = Tag.create(content: params[:tag])
BookmarkTag.create(bookmark_id: params[:id], tag_id: tag.id)
redirect '/bookmarks'
end
get '/users/new' do
erb :'users/new'
end
post '/users' do
user = User.create(email: params[:email], password: params[:password])
session[:user_id] = user.id
redirect '/bookmarks'
end
run! if app_file == [=14=]
end
self.find(id),在用户模型中,是可能有问题的 SQL 查询所在的位置。
我试过了;
"SELECT * FROM users WHERE id = #{id}"
和"SELECT * FROM users WHERE id = '#{id}'"
除此之外,我很难过。查询看起来不错,但 sinatra 有 none 个。
希望有人能帮我解决这个问题。
提前谢谢。
您使用散列参数调用 find
:
User.find(id: session[:user_id])
但它只需要 id
:
class User
...
def self.find(id)
...
end
...
end
然后你最终将一个散列插入到你的 SQL 字符串中,这导致无效的 HTML.
你应该说:
@user = User.find(session[:user_id])
只传递 User.find
期望的 id
。
您还让自己面临 SQL 注入问题,因为您在查询中使用不受保护的字符串插值而不是占位符。
您的 query
方法应该使用 exec_params
而不是 exec
并且它应该为占位符值采用一些额外的参数:
class DatabaseConnection
def self.query(sql, *values)
@connection.exec_params(sql, values)
end
end
然后调用 query
的东西应该在 SQL 中使用占位符并分别传递值:
result = DatabaseConnection.query(%q(
INSERT INTO users (email, password)
VALUES(, ) RETURNING id, email
), email, encypted_password)
result = DatabaseConnection.query('SELECT * FROM users WHERE id = ', id)
...
当 运行 我的应用程序使用 sinatra 时,我收到错误消息 PG::SyntaxError at /bookmarks
ERROR: syntax error at or near "{" LINE 1: SELECT * FROM users WHERE id = {:id=>"5"} ^
当我单击 /users/new
路线上的提交按钮时会发生这种情况,然后我应该将我带到索引路线 /
.
回溯提供以下信息
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/database_connection.rb in async_exec
@connection.exec(sql)
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/database_connection.rb in query
@connection.exec(sql)
/Users/BartJudge/Desktop/Makers_2018/bookmark-manager-2019/lib/user.rb in find
result = DatabaseConnection.query("SELECT * FROM users WHERE id = #{id}")
app.rb in block in <class:BookmarkManager>
@user = User.find(id: session[:user_id])
这是 database_connection 文件
require 'pg'
class DatabaseConnection
def self.setup(dbname)
@connection = PG.connect(dbname: dbname)
end
def self.connection
@connection
end
def self.query(sql)
@connection.exec(sql)
end
end
这是用户模型
require_relative './database_connection'
require 'bcrypt'
class User
def self.create(email:, password:)
encypted_password = BCrypt::Password.create(password
)
result = DatabaseConnection.query("INSERT INTO users (email, password) VALUES('#{email}', '#{encypted_password}') RETURNING id, email;")
User.new(id: result[0]['id'], email: result[0]['email'])
end
attr_reader :id, :email
def initialize(id:, email:)
@id = id
@email = email
end
def self.find(id)
return nil unless id
result = DatabaseConnection.query("SELECT * FROM users WHERE id = #{id}")
User.new(
id: result[0]['id'],
email: result[0]['email'])
end
end
这是控制器
require 'sinatra/base'
require './lib/bookmark'
require './lib/user'
require './database_connection_setup.rb'
require 'uri'
require 'sinatra/flash'
require_relative './lib/tag'
require_relative './lib/bookmark_tag'
class BookmarkManager < Sinatra::Base
enable :sessions, :method_override
register Sinatra::Flash
get '/' do
"Bookmark Manager"
end
get '/bookmarks' do
@user = User.find(id: session[:user_id])
@bookmarks = Bookmark.all
erb :'bookmarks/index'
end
post '/bookmarks' do
flash[:notice] = "You must submit a valid URL" unless Bookmark.create(url: params[:url], title: params[:title])
redirect '/bookmarks'
end
get '/bookmarks/new' do
erb :'bookmarks/new'
end
delete '/bookmarks/:id' do
Bookmark.delete(id: params[:id])
redirect '/bookmarks'
end
patch '/bookmarks/:id' do
Bookmark.update(id: params[:id], title: params[:title], url: params[:url])
redirect('/bookmarks')
end
get '/bookmarks/:id/edit' do
@bookmark = Bookmark.find(id: params[:id])
erb :'bookmarks/edit'
end
get '/bookmarks/:id/comments/new' do
@bookmark_id = params[:id]
erb :'comments/new'
end
post '/bookmarks/:id/comments' do
Comment.create(text: params[:comment], bookmark_id: params[:id])
redirect '/bookmarks'
end
get '/bookmarks/:id/tags/new' do
@bookmark_id = params[:id]
erb :'/tags/new'
end
post '/bookmarks:id/tags' do
tag = Tag.create(content: params[:tag])
BookmarkTag.create(bookmark_id: params[:id], tag_id: tag.id)
redirect '/bookmarks'
end
get '/users/new' do
erb :'users/new'
end
post '/users' do
user = User.create(email: params[:email], password: params[:password])
session[:user_id] = user.id
redirect '/bookmarks'
end
run! if app_file == [=14=]
end
self.find(id),在用户模型中,是可能有问题的 SQL 查询所在的位置。
我试过了; "SELECT * FROM users WHERE id = #{id}"
和"SELECT * FROM users WHERE id = '#{id}'"
除此之外,我很难过。查询看起来不错,但 sinatra 有 none 个。
希望有人能帮我解决这个问题。 提前谢谢。
您使用散列参数调用 find
:
User.find(id: session[:user_id])
但它只需要 id
:
class User
...
def self.find(id)
...
end
...
end
然后你最终将一个散列插入到你的 SQL 字符串中,这导致无效的 HTML.
你应该说:
@user = User.find(session[:user_id])
只传递 User.find
期望的 id
。
您还让自己面临 SQL 注入问题,因为您在查询中使用不受保护的字符串插值而不是占位符。
您的 query
方法应该使用 exec_params
而不是 exec
并且它应该为占位符值采用一些额外的参数:
class DatabaseConnection
def self.query(sql, *values)
@connection.exec_params(sql, values)
end
end
然后调用 query
的东西应该在 SQL 中使用占位符并分别传递值:
result = DatabaseConnection.query(%q(
INSERT INTO users (email, password)
VALUES(, ) RETURNING id, email
), email, encypted_password)
result = DatabaseConnection.query('SELECT * FROM users WHERE id = ', id)
...