Mac OSをアップデートするとMySQLがクラッシュすることがあるらしい?
状況
Mac OSのアップデートを実行、再起動後、MySQLが起動しなくなった。
現象
pidが消えた。エラーがたくさん出る。ググりまくって試行錯誤するものの解決できず。結局、MySQLのバージョンをあげたら再インストールできた。しかしバージョンをあげたことによって違う問題がでてきたりと、大変。
雑感
DBがポシャると開発できなくなるので大事。Dockerイメージつくっておいてクシャッたらいちから立て直すみたいなことができるようにしておきたいと思った。解決しないトラブルシューティングに何時間も費やすと心身の消耗が激しい。
入力フォームの値が以前のデータと同じだったら送信をキャンセルさせたい
状況
何らかのデータを更新するためのフォームがあるとして、入力された値が以前と同じ状態で送信されたらリクエストをキャンセルさせたい。
コード
$('input[type="test"]').on('submit', function(e) { var prev_val = $('.prev_val'); var new_val = $('.new_val'); if ( prev_val == new_val ) { e.preventDefault(); alert('同じ内容です。'); } })
DEMO
雑感
jQueryでテキストを取得する場合、pタグはtext()
、inputタグはval()
と使い分ける。間違えやすい。
【Ruby on Rails】capistranoによる自動デプロイ環境でタスクを定期実行させたい
状況
何らかのバッチ処理を本番サーバーで定期実行させたい。capistranoによる自動デプロイのついでにバッチ処理の設定もしてしまいたい。
前提
- Ruby on Rails
- capistrano
- whenever
方法
capistrano
capistranoの設定ファイルにwheneverの設定を追記する。
deploy.rb
などに以下を加える。
set :whenever_command, "bundle exec whenever" require "whenever/capistrano"
環境を指定するには
set :environments "production"
とすることでRAILS_ENV=production ~
相当のcronジョブが生成される。stagingで実行したいときは置き換えること。
複数の環境を設定する方法があるとおもうが、わからなかった。
whenever
そしてschedule.rb
に定期実行したいジョブを加える。
every 1.day, :at => '00:00 am' do runner "SomeStuff.new.delay.awesome_procedure" rake "jobs:work" end
runner "SomeStuff.new.delay.awesome_procedure"
は、delayed_jobsにキューを入れる。
次のrake "jobs:work"
でキュー入りしたジョブを取り出す。
キューするときに実行タイミングを引数で指定できる。
runner "SomeStuff.new.delay(run_at: 1.hour.from_now).awewome_procedure"
デキューされた1時間後にawesome_procedureが実行されることになる。
雑感
わかってしまえばシンプルに記述できるが、わかるまでが大変。
【RoR】モデルの属性を更新するフォームをつくりたい
状況
ユーザーのフォーム入力に従ってモデルの値を更新したい。
やり方
ビューで
form_for
を使う。コントローラーでstrong parameterを使ってパラメーターをフィルターする。
モデルの更新
前提
更新対象のモデル:article
title
属性をもつ。これを更新したい。
コード
ビュー
= form_for @article, url: "/article/update_article_title" do |f| =f.text_field :title, value: @article.title p
コントローラー
def update_arcicle_title return 404 is !update_params[:title] article = Article.find(update_params[:id]) if article.present? article.update_attributes(title: update_params[:title]) end redirect_to index_path end private def update_params params.require(:article).permit(:title) end
ビューから渡ってくるパラメーターについて
ビューの
= form_for @article, url: ...
に入力&送信されたパラメーターは次のようなハッシュとなる。
article { :title => "great article" }
これをストロングパラメーターでフィルターしたい。
require
とpermit
で二段階にフィルターする。はじめはモデル名、次に属性名で絞り込む。
params.require(:article).permit(:title) # => "great article"
エンターキーが押された時のページ遷移を防ぎたい
状況
任意のテキストボックスに何か文字列を入力していて、入力を確定するつもりでエンターを押したら、意図せず変なところにジャンプしてしまうのを防ぎたい。
コード
$('input[type="text"]').on('keypress', function(e) { if( e.which == 13 ) { e.preventDefault(); } });
DEMO
thisを関数に渡したい
状況
jsでthisを関数の引数として渡したい。
しかしそのまま引数の名前をthis
とするとエラーになる。予約語だから引数の名前にはできないのだ。
かわりに_this
とすればよい。
コード
$('input[type="text"]').on('click', '#mandatory', function() { do_something(this); } function do_something(_this) { // なんかの処理 }
DEMO
【ActiveRecord】3つ以上のテーブルをJOINしたい
状況
3つ以上のテーブルをJOINしたい。
想定するモデル
記事、段落、文といったモデルを考えてみる。記事は複数の段落を含む。段落は複数の文を含む。以下のモデルがあるものとする。
# articles has_many :paragraphs # paragraphs belongs_to :article has_many :sentences # sentences belongs_to :paragraph
書き方
A) 特定のsentenceが所属するarticleを取得する(孫から先祖へ)。
Sentence.eager_load(paragraph: :article).where(sentences: {id: ?})
B) 特定のarticleに含まれるsentencesを取得する(先祖から孫へ)。
Article.eager_load(paragraphs: :sentences) .where(articles: { id: ? })
where
にはテーブル名につづけてハッシュでカラムと値を指定する。テーブル名を渡さないとエラーになる。
OK
.where( sentences: { id: ? })
NG
.where( id: ? )
どのテーブルのidなのかがわからないからダメ。
SQLなら
上記コードから以下のクエリが生成される。
A)
SELECT * FROM sentences LEFT OUTER JOIN paragraphs ON paragraphs.id = sentences.paragraph_id LEFT OUTER JOIN articles ON paragraphs.article_id = articles.id WHERE sentence.id = ?
B)
SELECT * FROM articles LEFT OUTER JOIN paragraphs ON articles.id = paragraphs.article_id LEFT OUTER JOIN sentences ON paragraphs.id = sentences.paragraph_id WHERE sentence.id = ?
モデル名、単数/複数?
複数形または単数形のどちらにするのかはモデルの関連付けに従う。
たとえば上記 B)の場合、Articleは複数のParagraphsをもつので、eager_loadの第一引数は複数形のparagraphs
とする。同じように、paragraphsは複数のsentencesをもつので、第二引数も複数形のsentences
とする。
もっとJOINしたい
たとえば記事の筆者も表示したくなったとする。そのためにauthors
モデルを追加でJOINしたい。このとき、任意の著者によるsentence、paragraph、articleは次のようにして取得できる。
Sentence.eager_load(paragraph: {article: :author}) .where(authors: {name: ?})
モデル名をハッシュでネストすればOK。
(paragraph: {article: :author})
雑感
Railsガイドに複数モデルの関連付けの方法が紹介されている。読んでもわからなかったので、色々ググって3つ以上のテーブルをつなぐ記法を調べる必要があった。
Active Record クエリインターフェイス | Rails ガイド
Active Recordの記法がわからない場合、生SQLを食わすという手段もある。
https://railsguides.jp/active_record_querying.html#sql%E3%81%A7%E6%A4%9C%E7%B4%A2%E3%81%99%E3%82%8B
find_by_sqlに生クエリを渡して実行するやり方についてメモした。