Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

JuliaのGenieを使ってDB操作をするところまで

別サイト

に書いていたのだけどサ終してしまったので移行した記事その2
2019/03/06のもの

Julia

Juiliaという言語があるのを最近知ったのでサンプルに従って書いてみる

Genie

Julia向けにGenieというwebフレームワークがあったのでそれを使ってDB接続するところまでをやっていく

環境構築

https://julialang.org/downloads/
からJuliaをダウンロード、インストール

$ julia --version
julia version 1.1.0

自分が入れた段階では1.1.0だった

Genieインストール、アプリ作成

$ julia
julia> using Pkg
julia> Pkg.clone("https://github.com/essenciary/Genie.jl")
julia> using Genie
julia> Genie.REPL.new_app("app")
julia> ] ## ]をいれるとパッケージモードになる
pkg> add https://github.com/essenciary/SearchLight.jl  ##DB接続用にSearchLightをいれる

これで基本は完了。
./bin/serverなどで起動すると
http://localhost:8000/
でトップページが表示できました

実装

https://github.com/essenciary/Genie.jl
Julia web frameworkのGenieでTODOリストを作る
公式ドキュメントや他の方がやられていたのを参考に実装していく
app/resources配下にコントローラやビューを作成する作法らしい

今回作成したファイル

  • app/resources/tests/Tests.jl(生成は自動)
  • app/resources/tests/TestsController.jl
  • app/resources/tests/TestsValidator.jl(生成は自動)
  • app/resources/tests/views/new.jl.html
  • app/resources/tests/views/tests.jl.html

修正したファイル

  • config/database.yml
  • config/routes.jl

ソースは後述

database設定

config/initializers/searchlight.jlのコメントを外す

config/initializers/searchlight.jl
using SearchLight, SearchLight.QueryBuilder

Core.eval(SearchLight, :(config.db_config_settings = SearchLight.Configuration.load_db_connection()))

SearchLight.Loggers.empty_log_queue()

if SearchLight.config.db_config_settings["adapter"] != nothing
  SearchLight.Database.setup_adapter()
  SearchLight.Database.connect()
  SearchLight.load_resources()
end

database.ymlに設定追加

database.yml
env: dev

dev:
  adapter: SQLite
  database: db/tests.sqlite
  host:
  username:
  password:
  port:
  config:

DB接続、モデル作成

julia> SearchLight.Configuration.load_db_connection()
julia> SearchLight.Configuration.load_db_connection() |> SearchLight.Database.connect!
julia> SearchLight.db_init()
julia> SearchLight.Generator.new_resource("Test")

作成されたマイグレーションファイルに適当にカラムを設定

db/migrations/xxxxx_create_table_tests.jl
module CreateTableTests

import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table

function up()
  create_table(:tests) do
    [
      primary_key()
      column(:content, :string)
      column(:done, :bool)
    ]
  end

  add_index(:tests, :content)
end

function down()
  drop_table(:tests)
end

end

テーブル作成

julia> SearchLight.Migration.last_up()

モデルファイルもマイグレーションファイルと同様にカラム設定をいれる
seedファンクションにて初期データ用の処理も追加

app/resources/tests/Tests.jl
mutable struct Test <: AbstractModel
  ### INTERNALS
  _table_name::String
  _id::String
  _serializable::Vector{Symbol}

  ### FIELDS
  id::DbId
  content::String
  done::Bool

  ### constructor
  Test(;
    ### FIELDS
    id = DbId(),
    content = "",
    done = false

  ) = new("tests", "id", Symbol[],                                                ### INTERNALS
          id, content, done                                                             ### FIELDS
          )
end

function seed()
  SampleTests = [
    ("ほげ", true),
    ("ほげほげ", false),
    ("げほげほ", false)
  ]
  for test in SampleTests
    Test(content = test[1], done = test[2]) |> SearchLight.save!
  end
end

初期データ投入

julia> ]
pkg> activate .
pkg> # Ctrl-C
julia> using Genie
julia> Genie.REPL.load_app()
julia> using Tests
julia> Tests.seed()

コントローラ、ビュー、ルートの修正

コントローラ作成->ビュー作成->ルート作成
みたいな感じで作成していきました
動かすたびにエラーでたり試行錯誤が多かったけど最終的に

  • DBからselectしたものを表示
  • DBにデータをinsert
  • DBのデータをupdate

といったところができた

コントローラ

app/resources/tests/TestsController.jl
module TestsController

using Genie.Renderer
using Genie.Router
using SearchLight
using Tests

# トップ
function index()
  html!(:tests, :tests, tests = SearchLight.all(Tests.Test))
end

# 新規作成
function new()
  html!(:tests, :new)
end

# 新規登録
function create()
  # 作成
  Tests.Test(content = @params(:test_content), done = false) |> save
  redirect_to(:get_tests)
end

# 更新
function update()
  # 既存データのselect
  test = SearchLight.find_one_by!!(Tests.Test, :id, @params(:test_id))
  # リクエストパラメータ(なんかstringで受けるのでそのままbool判定できなかった)
  in_done = ifelse(@params(:test_done) == "true", true, false)
  # 更新処理
  Tests.Test(id = @params(:test_id), content = test.content, done = in_done) |> save!
  # トップにリダイレクト
  redirect_to(:get_tests)
end

end

ビュー

app/resources/tests/views/new.jl.html
<form action="$(Genie.Router.link_to(:create_test))">
  内容:<input type="text" name="test_content" /></br>
  <input type="submit" value="作成" />
</form>

velocityみたいな感じで書ける

app/resources/tests/views/tests.jl.html
<a href="$(Genie.Router.link_to(:new_test))">作成</a>
<ul>
<%
  if length(@vars(:tests)) == 0
    "データがありません。"
  else
    @foreach(@vars(:tests)) do test
      if test.done
      "<li><s>$(test.content)</s><a href=" * Genie.Router.link_to(:update_test) * "?test_id=" * string(get(test.id)) * "&test_done=false" * ">&nbsp falseに戻す</a></li>"
      else
      "<li>$(test.content)<a href=" * Genie.Router.link_to(:update_test) * "?test_id=" * string(get(test.id)) * "&test_done=true" * ">&nbsp trueにする</a></li>"
      end
    end
  end
 %>
</ul>

ルート

config/routes.jl
using Genie.Router
using TestsController

route("/") do
  serve_static_file("/welcome.html")
end

# トップページ
route("/tests", TestsController.index, named = :get_tests)
# 新規登録画面
route("/tests/new", TestsController.new, named = :new_test)
# 登録処理
route("/tests/create", TestsController.create, method = GET, named = :create_test)
# 更新処理
route("/tests/update", TestsController.update, method = GET, named = :update_test)

感想

コードは見やすく短くかけていい感じだと思う
ただまだよくわからないところも多く(サンプルの通りでも怪しいところがあったり)
エラーが起きたときにどう対処すればいいかがわからないことが多かった
同じソースでも起動し直したら動いたりするのも何故なのかもよくわからない
POSTメソッドでもなぜかエラーが出たり。。。

sireikan
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away