1 Câu hỏi: PG :: SyntaxError tại / bookmark - Tôi không thể hiểu tại sao truy vấn SQL sai

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Khi chạy ứng dụng của tôi bằng sinatra, tôi nhận được thông báo lỗi PG::SyntaxError at /bookmarks ERROR: syntax error at or near "{" LINE 1: SELECT * FROM users WHERE id = {:id=>"5"} ^ Nó xảy ra khi tôi nhấp vào nút gửi trên tuyến /users/new sau đó sẽ đưa tôi đến chỉ mục tuyến /.

Backtrace cung cấp thông tin sau

/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])

Đây là tệp cơ sở dữ liệu_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

Đây là mô hình người dùng

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

Đây là bộ điều khiển

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 == $0
end

self.find (id), trong mô hình người dùng, là nơi truy vấn SQL có khả năng vi phạm.

Tôi đã thử; "CHỌN * TỪ người dùng WHERE id = # {id}"

và "CHỌN * TỪ người dùng WHERE id = '# {id}'"

Ngoài ra, tôi đã bối rối. Truy vấn có vẻ ổn, nhưng sinatra không có câu hỏi nào.

Hy vọng ai đó có thể giúp tôi giải quyết vấn đề này. Cảm ơn, trước.

    
0
1 Câu trả lời                              1                         

Bạn đang gọi find với đối số băm:

User.find(id: session[:user_id])

nhưng nó chỉ mong đợi id:

class User
  ...
  def self.find(id)
    ...
  end
  ...
end

Sau đó, bạn kết thúc nội suy một hàm băm vào chuỗi SQL của mình dẫn đến HTML không hợp lệ.

Bạn nên nói:

@user = User.find(session[:user_id])

để vượt qua chỉ idUser.find mong đợi.

Bạn cũng để mình mở các vấn đề tiêm SQL vì bạn đang sử dụng phép nội suy chuỗi không được bảo vệ cho các truy vấn của mình thay vì giữ chỗ.

Phương thức query của bạn nên sử dụng exec_params thay vì exec và cần thêm một số tham số cho các giá trị giữ chỗ:

class DatabaseConnection
  def self.query(sql, *values)
    @connection.exec_params(sql, values)
  end
end

Sau đó, những thứ gọi query nên sử dụng trình giữ chỗ trong SQL và chuyển các giá trị riêng biệt:

result = DatabaseConnection.query(%q(
  INSERT INTO users (email, password)
  VALUES($1, $2) RETURNING id, email
), email, encypted_password)

result = DatabaseConnection.query('SELECT * FROM users WHERE id = $1', id)

...
    
1
2019-05-08 20: 59: 31Z
  1. Cảm ơn, đã sắp xếp các lỗi Sinatra. Tôi cũng gặp lỗi Rspec do cùng một vấn đề, mà giờ đây tôi cũng đã sắp xếp nhờ vào sự giúp đỡ của bạn.
    2019-05-08 22: 31: 02Z
nguồn đặt đây