hotwire-love / touhyosan Goto Github PK
View Code? Open in Web Editor NEWHotwire.love で使う投票ツール
License: MIT License
Hotwire.love で使う投票ツール
License: MIT License
touhyousanでpoll_idが指定された場合に、choice毎のstatusの値の個数を取得する。
touhyousanの仕様から、必ず全てのchoiceについてstatusが設定されるので、choicesテーブルに対して、vote_detailsテーブルをinner joinして求めてみた。
ただし、3種類あるstatusの値すべてが設定されるとは限らないため、プログラム中で指定されていないstatusの値を確認する必要がある。
また、order by は人間がselect結果を見やすくするためのもので、プログラムでは必要ないと思う。
select vd.choice_id, vd.status, count(vd.choice_id) from choices as c inner join vote_details as vd on c.id = vd.choice_id where c.poll_id = 54 group by vd.choice_id, vd.status order by vd.choice_id, vd.status;
choice_id | status | count
-----------+--------+-------
161 | 0 | 2
161 | 1 | 1
161 | 2 | 4
162 | 0 | 1
162 | 1 | 1
162 | 2 | 5
163 | 0 | 2
163 | 2 | 5
N+1問題の改善等。
具体的なポイントを挙げ始めるといろいろありそう。
#36 のタスクが残り一つになったので、issueを分けました。
ドラッグアンドドロップしやすいUIにしたい。
ローカルだと起きない。なぜ??
https://touhyosan.hotwire.love/polls/1
ローカルで起動すると無関係なfaviconが表示されることがあるので。
db/seed.rbのTODOである、VoteDetailをつくったら、削除するコードと、登録するコードを追加する
自分が使う方をコピペしてもらう
PostgreSQLやRedis等が必要になっているのでDocker化した方が開発に参加しやすいかも?
RSpecか、Minitestか、どっちにするか?
「猫でもわからHotwire入門 Turbo編」で紹介されていたのですが、以下のCSSを適用すると、turbo-frame領域に枠が表示されます。
デバッグ時には有用化と思い提案します。
全てではなく、上位 1 - 3 までだけ登録する?
現在、モブプロをする場合は、ドライバー役が、hotwire-love/touhyousanをフォークし、フォークしたリポジトリをローカルにクローンし、ローカルに対してコミットした後、勉強会終了後にフォーク先にプッシュし、そしてhotwire-love/touhyousanにプルリクエストすることになっています。
ただしこのやり方の場合、プルリクエストを送ってから、mainブランチにマージされるまでに時間がかかると、勉強会参加者が後日勉強会で行った内容を確認しようと思っても、なかなか確認することができません。
mainブランチにマージする際には、勉強会で行ったことそのままではなく、整理・修正したほうがいい場合もあると思います。
ただ勉強会で行ったことを確認したい場合には、(整理・修正されていなくて)そのままの状態であっても、すぐにみることができたほうが嬉しいと思います。
このため、各勉強会毎にhotwire-love/touhyousanにモブプロ用のブランチを切り(例:vol12)、そこに一旦モブプロ時のcommitをpushし、勉強会の終わりに、その回のモブプロ用のブランチから、mainブランチへのマージ用のブランチを切り(例:vol12_pr)、そのブランチに対するプルリクエストを送って、それをmainブランチにマージしてはどうでしょうか。
vol12_prは作業用のブランチですので、mainブランチにマージした後は削除してかまわないと思います。
逆にvol12のほうは、ある程度の期間は残しておいた方がいいと思います。
具体的なポイントを挙げ始めるといろいろありそう。
以下のcommitに対するバグ報告です。
以下のルーティングが設定されているため、フォームでsubmitした場合、POST /polls/:poll_id/votes polls/votes#createが該当する。
Prefix | Verb | URL | コントローラ#アクション |
---|---|---|---|
root | GET | / | polls#new |
poll_votes | POST | /polls/:poll_id/votes(.:format) | polls/votes#create |
new_poll_vote | GET | /polls/:poll_id/votes/new(.:format) | polls/votes#new |
edit_poll_vote | GET | /polls/:poll_id/votes/:id/edit(.:format) | polls/votes#edit |
poll_vote | PATCH | /polls/:poll_id/votes/:id(.:format) | polls/votes#update |
PUT | /polls/:poll_id/votes/:id(.:format) | polls/votes#update | |
polls | POST | /polls(.:format) | polls#create |
new_poll | GET | /polls/new(.:format) | polls#new |
poll | GET | /polls/:id(.:format) | polls#show |
選択肢の順番の入れ替えをフォーム上で行う場合、デフォルトのルーティングから外れることにつなばるので、以下の点を仕様として検討、決定しておく必要があるのではないでしょうか。
bin/setup
== Installing dependencies ==
The Gemfile's dependencies are satisfied
yarn install v1.22.19
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.17s.== Preparing database ==
'
rails aborted!
KeyError: key not found: "REDIS_URL"
/home/ykominami/cur/rails7/HotWire/hotwire.love/hotwire.love/touhyosan/config/cable.yml:11:infetch' /home/ykominami/cur/rails7/HotWire/hotwire.love/hotwire.love/touhyosan/config/cable.yml:11:in
/home/ykominami/cur/rails7/HotWire/hotwire.love/hotwire.love/touhyosan/config/environment.rb:5:in `'
Tasks: TOP => db:prepare => db:load_config => environment
(See full trace by running task with --trace)== Command ["bin/rails db:prepare"] failed ==
app/controller/polls/votes_controller.rbにおいて、updateメソッド中の@vote.updateで失敗(validateionエラー)した場合も、成功時と同様にフォーマットに応じたrenderを行う必要がある。
また、成功時と同様に、app/views/polls/votes/edit.turbo_stream.erbも必要になる。
現在のtouhyousanのフラッシュメッセージは、もともと意図していたものとは、異なる挙動になっていると思います。
turbo_driveを利用していた場合は、意図通りだと思うのですが、turbo_frame, turbo_streamで画面遷移をしない場合は、ずっと表示されっぱなしになっています。
また、さらに非同期にブロードキャストで変更されると、フラッシュメッセージが何を伝えるのか分からなくなると感じています。
draggable、2年半くらい前に shopify が手を引いて、引き継ぐ
メンテナが現れず、開発が(ほぼ)停止している ので、替わりのライブラリ
(Sortable etc)にしたほうがよいかもしれません。
とのことなので、別のライブラリに乗り換えた方がいいかもしれませんね。
このままdraggableで作っていってもいいかもしれないけど、開発が進めば進むほど乗り換えが大変になるので、やるなら「今でしょ!」かもしれない。
RailsのER図をMermaidで柔軟に生成できるGemを作りました
GitHub - koedame/rails-mermaid_erd: Generate Mermaid ERD from your Ruby on Rails application.
Gemfileにgemを指定して、bundle install後、以下を実行すると、mermaid_erd/index.htmlが生成されます。
bundle exec rails mermaid_erd
HTMLファイル1個のみですが、JavaScript用いて、いろいろなパターンで表示できます
もう少し魅力的なデザインになると嬉しい
選択肢の個数分の投票数があった場合、すべての選択肢のスコアが同点になるケースが考えられます。
現在は上位3つを選ぶという仕様ですが、例えば4つの選択肢があった場合に、すべてスコアが同点の場合にどうするかということです。
これは事前にどう扱うかを決めておくという問題ですので、備忘のために登録しておきます。
直接touhyousanとは関係ないのですが、touhyousanで利用しているbootstrapをrails newで指定してRailsアプリケーションを新規作成しようとすると、最終的にnpmがエラーを返して失敗します。
具体的にはnpmに対して、package.jsonファイルのscriptsフィールドに以下の内容を追加する時にエラーになります。
npm pkg set scripts.watch:css="nodemon --watch ./app/assets/stylesheets/ --ext scss --exec "yarn build:css""
はnpmに対するコマンドのUSAGEエラーになります。
ここで、以下のようにシングルクォートで囲むとエラーにならなくなります。
--exec 'yarn build:css'
エラー発生を確認したのは、Windows 10のWSL2でdebianパッケージの場合です。
asdfでruby, nodeをバージョン管理しています。
Ruby(3.0.2, 3.1.2, 3.2.2),Rails(7.0.8, 7.0.2.3), node(14.17.0, 17.1.0, 18.12.1, 19.8.1)のどの組み合わせでもエラーが発生しました。
エラーが発生しなかったのは、Mac OS Montley 12,6.9 の場合でした。
こちらもasdfでRuby, Nodeをバージョン管理していました。
こちらはどの組み合わせでもエラーが発生しましませんでした。
ただしnpmのバージョンは6.14.18でした。
そこで、Windows 10, WSL2でもnpmのバージョン6.14.18をグローバルにインストールして実行すると、エラーが発生しなくなりました。
npmのバージョン6.14.18から最新版(10.1.0)のどこからエラーが発生するかは未確認です。
npm pkg set <key>=<value>
において、を""で囲んだ時に、その中でさらに文字列を""で囲むことが、npmの新しいバージョンで認められなくなっているようです。具体的にどのバージョンから認められなくなったかまでは確認できていません。
app/views/polls/_result.html.erb のコメント欄のrowに不要なが含まれている。これを削除すれば意図した位置に投票のコメントが表示される。
$ bin/setup
== Installing dependencies ==
The Gemfile's dependencies are satisfied
yarn install v1.22.19
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.11s.== Preparing database ==
'
rails aborted!
KeyError: key not found: "REDIS_URL"
/home/ykominami/cur/rails7/HotWire/hotwire.love/hotwire.love/touhyosan/config/cable.yml:11:infetch' /home/ykominami/cur/rails7/HotWire/hotwire.love/hotwire.love/touhyosan/config/cable.yml:11:in
/home/ykominami/cur/rails7/HotWire/hotwire.love/hotwire.love/touhyosan/config/environment.rb:5:in `'
Tasks: TOP => db:prepare => db:load_config => environment
(See full trace by running task with --trace)== Command ["bin/rails db:prepare"] failed ==
勉強会Vol.18で実装したSystem specを実行するためには、bin/setupの実行以外に、PlayWrightをインストールする必要がある.
しかし、README.mdにそれに関する記述がない。
app/views/polls/votes/result.turbo_stream.erbで表示されるTurboStreamsとしてreplaceされた「投票を作成」リンクが、turbo_frameタグに囲まれていないため、replace後は単なるテキストリンクになっている。
replaceされる対象として、「投票を作成」リンクをturbo_frame_tagで囲んでおく必要がある。
Hotwire.love meetup Vol.21(2023-09-14)のフリートークにて、「Modelに対するValidation定義とは異なるDBのカラム制約を与えた状態で、DBに保存するときに制約違反が発生しても、500エラーページとして表示されない」というテーマで盛り上がりました。
ただし、最終的な結論がでずに時間切れとなりました。
今まではsave!メソッドを呼び出し、制約違反の例外が発生したらエラーページが表示されていたが、最近画面が何も変化しないことに遭遇した、Turboが握りつぶしているのではないかという疑問でした。
いくつかのやり方でコード変更し、挙動が変わることは確認しましたが、なぜエラーページが表示されないかには辿り着けませんでした。
勉強会の後、Railsのエラーページ表示の仕組みを色々調べて、やっと腑に落ちる状態になりました。フリートーク中に出された色々な仮説に基づくコード変更の根拠が理解出来るようにはなったのですが、今まで出来ていたのに最近できなくなったというという事に対しては、説明できないとも感じました。
そこで思いついたのは、「実はDBカラムに対する制約違反は発生していない」という仮説です。
そもそも制約違反が発生していないのならば、エラーページは表示されません。
「制約違反が発生している」という前提で話していましたが、db/schema.rbをみて確認したり、railsのコンソールでsaveメソッドを呼び出して例外が発生するのかを確認してはいませんでした。またValidationが通った後にDBに保存するのですから、Validationが通らなかった場合は、保存しないため制約違反も発生しません。
実際に、Ruby 3.2.2, Rails 7.0.8、PostgrSQLにて
rails g scaffold blog title:string content:
とし、db/schema.rbが以下の通りになるようにmigrateして、試してみました。
ActiveRecord::Schema[7.0].define(version: 2023_09_17_002252) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "blogs", force: :cascade do |t|
t.string "title", null: false
t.text "content", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
簡単にするため、Modelに対してはValidationを定義しませんでした。
Not Null制約を与えているので、blog_paramsではなく(フォームから送信されたパラメータでは値がnilではなく空文字列になってしまうため)明示的に値がnilであるハッシュをsaveメソッドに与えて呼び出しました。
def create
hash = { title: nil, content: nil }
# @blog = Blog.new(blog_params)
@blog = Blog.new(hash)
# raise
# @blog = Blog.find(100)
# @blog.save! # (A)
respond_to do |format|
if @blog.save # (B)
# if @blog.valid? # (A)の場合はこちらを有効にしました
format.html { redirect_to blog_url(@blog), notice: "Blog was successfully created." }
format.json { render :show, status: :created, location: @blog }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @blog.errors, status: :unprocessable_entity }
end
end
end
結果は、(A)の場合はsave!メソッド呼び出し時、(B)の場合saveメソッド呼び出し時に、以下の例外が発生しエラーページが表示されました。
ActiveRecord::NotNullViolation in BlogsController#create
saveメソッドはDB保存に成功したらtrue、失敗したらfalseを返します。
Validation結果はerrorsに格納されています。
save!メソッドは、DB保存に失敗したら、RecordNotSavedエラーをraiseします。
saveとsave!の差は成功、失敗を値として返すか、失敗時に例外をraisesするかであり、呼び出し先でraiseされた例外はrescueしないようです。
https://github.com/hotwire-love/docs/wiki/Hotwire.love-meetup-vol.19 を参照。
(ただし、どういう方針で実装すべきかは要検討)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.