Newer
Older
2022-Database / 203-webapp / app.rb
@”Sato ”Sato on 17 Jan 2023 2 KB fix
require 'sinatra'
require 'sqlite3'
# 乱数生成ライブラリを読み込む
require 'securerandom'

db = SQLite3::Database.new('answers.db')
#db.results_as_hash = true   #ハッシュ化。配列の何番とか分からないから。

# セッション機能を有効化
enable :sessions
# セッション秘密鍵を生成
# この鍵でセッション情報が署名され、ブラウザに返される。
# Webアプリ再起動で鍵が新しくなってしまい全てのセッションが失われるため、
# 固定したい場合はここを固定の秘密鍵に置きかえる。
set :session_secret, SecureRandom.hex(64)

# セッションの有効期限を30日に設定
set :sessions, :expire_after => 60 * 60 * 24 * 30

# クッキーを他のドメインのWebサイトには送らない
set :sessions, :same_site => 'Strict'

# 投稿された名前とメッセージの一覧を返す。
get '/' do
    # 名前とメッセージが未投稿のメッセージ以外をSELECTする
    answers = db.execute(<<-SQL)
      SELECT name, message
        FROM answers
        WHERE name IS NOT NULL
          AND message IS NOT NULL;
    SQL
    erb(:answers, locals: {'answers' => answers})
end

get '/answers.json' do
    # 名前とメッセージが未投稿のメッセージ以外をSELECTする
    answers = db.execute(<<-SQL)
      SELECT name, message
        FROM answers
        WHERE name IS NOT NULL
          AND message IS NOT NULL;
    SQL
    json(answers)
end

# 回答フォームを返す。
get '/question/:answer_id' do 
      # get_first_rowメソッドで、SELECTした結果の最初の行だけを得る
  # answer_idが正しければ {"answer_id"=>"リクエストされたID", "name"=>nil, "message"=>nil}、
  # 誤っていればnilになる
  answer = db.execute(<<-SQL, answer_id: params['answer_id'])[0]
  SELECT answer_id, name, message
    FROM answers
    WHERE answer_id = :answer_id;
    SQL

    # もしDBに登録されていないanswer_idが来た場合、403を返し終了する。
    unless answer
        halt 403 
    end

    # セッションIDにanswer_idを追加。
    session['answer_id'] = answer['answer_id']

    # 回答フォームを生成し返す。
    pp answer
    erb(:question, locals: answer)
end

# 回答を受信し、お礼ページを返す。
post '/answer' do
    # 正常なセッション情報を持たない場合、403を返し終了する。
    halt 403 unless session['answer_id']
      
    # 入力された情報とセッションのanswer_idを元にDBを更新。
    db.execute(<<-SQL, answer_id: session['answer_id'], name: params['name'], message: params['message'])
        UPDATE answers
          SET name = :name, message = :message
            WHERE answer_id = :answer_id;
        SQL
      
    erb(:answer, locals: {'answer_id' => session['answer_id'] })
end

# なんらかのエラーが発生し、halt 403が呼ばれたらここに到達
error 403 do
    'アクセスが拒否されました。'
end