- 投稿日:2020-06-30T20:58:01+09:00
JavaScript/jQuery初心者が、アコーディオンメニューの開閉に伴って回転する矢印アイコンをなんとか実装したときの記録
はじめに
JavaScript/jQuery初心者が、コンテンツの開閉状態と連動する矢印アニメーションを、jQueryで実装するまでにやったことの記録です。
3行で
this
でクリックした要素にだけ処理を行う- アニメーション用のCSSを書く
toggleClass
でアニメーション用クラスの付け替えをする環境 + 前提
Rails 5.2.4.3
Ruby 2.6.5
Bootstrap 4.5.0
jquery-rails 4.4.0
sass-rails 5.1.0このポートフォリオに実装
YWT QuestBootstrapのカードを使用。
カードコンポーネントによるアコーディオンを実装していて、card-header
をクリックすると開閉する。やりたいこと
- このようなカードが並んでいて、開閉可能なものには矢印がついている。
- カードのヘッダー部分をクリックすることで開閉。
- カードが開いた時に矢印も回転(アニメーション)する。
- カードが閉じる時に矢印が回転(アニメーション)し元の状態に戻す
実装に必要そうなこと
card-header
をJavaScriptで指定し、クリックされた時にクラス名を追加する。- 追加したクラスに、アイコンの表示を変えるCSSを書く。
- もう1度クリックされた時には上で追加されたクラスを削除する。
実際にやったこと
1. viewファイルに直書きではなく、JavaScriptを読み込んで使う
まず、
assets/javascripts/logs/index.js
を読み込む設定をする。rails 任意のviewのみで、特定のjsを読み込む方法 - Qiita
logs/index.js
はviews/logs/index.slim.html
に対してだけ読み込ませたいので、上記を参考にviewファイルの下部に以下を記述。views/logs/index.slim.html<%= javascript_include_tag 'logs/index.js' %>2. jQueryでクリックイベントを追加する
card-header
部分をクリックすることで開閉可能で、カードが開いた時に矢印も回転するのであれば、card-header
をクリックした時に、矢印が回転するような処理 を書かないといけない。
card-header
はココ
card-header
をクリックした、とJavaScript側に分かってもらえてるかどうかをまずチェック。logs/index.js$(function(){ $('.card-header').click(function(){ alert("click event") }); });
card-header
をクリックしてアラートが出ればOKどうやらうまくいってるみたい。
3. カードの開閉状態で条件分岐させる
次に、クリックしたカードが開くかどうかをチェック。
現在はcontentカラム(詳細文)が空でなければ開くし、card-header
の文字の右側に矢印が表示される。つまり矢印の有無でカードが開くかどうかをチェックできる、と考えた。
クリックしたcard-header
にfa-chevron-down
というクラスが存在すれば開く、しなければ開かない。jQueryに
find
という子孫要素を取得できるメソッドがあったので使ってみる。【jQuery入門】find()で子要素を取得する手法まとめ! | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト
find(expr) - jQuery 日本語リファレンス以下のようなコードを書いた。まずは条件分岐が成功するかどうかをチェックする。
logs/index.js$(function(){ $('.card-header').click(function(){ var icon = $(this).find('.fa-chevron-down'); // 本文がなく、アイコンがないcard-headerをクリックした時はundefinedが返されることを利用した if(icon[0] !== undefined) { console.log("true"); } else { console.log("false"); } }); });最初は
icon[0] == "<i class=\"fas fa-chevron-down\"></i>"
と、icon[0]
に入っている情報そのものと照らし合わせたり
icon[0].toString();
として文字列に変換してから比較したり
indexOf
を使って前方一致(<i class
だけ等)で検索をかけてみたりしたが、全て失敗。どうしよう?と
console.log
を見ていると、開閉できないカードを押したときundefined
が返ってきているのを発見。「じゃあ、
undefined
が返ってきていないときにアニメーション用の処理をすればいいのでは……?」と考えて、
if
の中身をif(icon[0] !== undefined)
と書き換えることで、開くカードのcard-header
をクリックしたときにはtrue
が、開かないカードのcard-header
をクリックしたときにはfalse
が返ってくるようになった。4. 矢印をアニメーションさせる処理を書く
rotate() - CSS: カスケーディングスタイルシート | MDN
矢印を回転させるには
rotate()
プロパティでアイコンを回転させれば良いと考えた。
しかし、肝心のアニメーションの実装は……?jQueryでCSSのtransform: rotate()を使った回転アニメーションする際のメモ ‹ jQuery ‹ JavaScript ‹ emwaiblog
この記事では、回転用のクラス名を追加することで、回転を実装している。
また、transition
を使うことでtransform
をアニメーション化している。
transition
のオプションやプロパティについてはここを参考にした。まず、開閉に伴ってクラスを付けたり外したりする処理をjQueryで書く。
assets/javascripts/logs/index.js$(function(){ $('.card-header').click(function(){ var icon = $(this).find('.fa-chevron-down'); // 本文がなく、アイコンがないcard-headerをクリックした時はundefinedが返されることを利用した if(icon[0] !== undefined) { $('.fa-chevron-down').toggleClass("spined-icon") } // else以下を削除 }); });
toggleClass
で、fa-chevron-down
クラスを持つ要素にspined-icon
クラスがついてなければ追加、ついてたら削除する。これも検証ツールで確認する。
<i class="fas fa-chevron-down>"
の横にspined-icon
が追加されているのが確認できた。CSSで
spined-icon
に矢印を回転させる処理を書く。assets/stylesheets/logs/index.scss.spined-icon { transform: rotate(90deg); transition-duration: 0.5s; }
transform: rotate(90deg);
で要素を90度回転、それが始まってから終わるまでの時間をtransition-duration: 0.5s
で設定している。「0.5秒かけて要素を90度回転させてください」ということ。実際の動きを見てみる。
閉じるときのアニメーションがない。それはともかく……
クリックしてないカードの矢印も動いちゃってる……
何がいけなかったのか?
コードをもう一度見てみる。
assets/javascripts/logs/index.js$(function(){ // 'card-header'クラスを持つ要素をクリックしたとき、 $('.card-header').click(function(){ // 'card-header'クラスの子孫要素の中から'fa-chevron-down'クラスを持つ要素を探し、変数iconに格納する var icon = $(this).find('.fa-chevron-down'); if(icon[0] !== undefined) { // 'fa-chevron-down'クラスを持つ要素に'.spined-icon'クラスを追加(既にある場合は削除) $('.fa-chevron-down').toggleClass("spined-icon") } }); });このコード
$('.fa-chevron-down').toggleClass("spined-icon")
では、fa-chevron-down
クラスを持つ全てのi
要素にspined-icon
クラスを付与することになってしまい、全ての矢印が回転してしまう。「クリックした要素のみ」「クリックした要素 jQuery」等で検索していると、この記事を見つけた。
jQueryの$(this)の使い方(どこを指してるのか?)ここに、
this
を使ってクリックした要素にのみ処理を行っている例と、this
ではなく要素(記事中ではp
)を指定してしまった時の例があり、後者では自分の失敗例と同じで全てのp
要素に処理が行われてしまっている。これを参考に、クリックした
card-header
のi
にのみクラスを追加/削除する処理を行うコードを考える。
また、クリックしたcard-header
のi
に処理を行うため、再びfind
を使った。jQueryで子要素を取得するいくつかの方法〜children,find,contents
完成形
logs/index.js$(function(){ $('.card-header').click(function(){ var icon = $(this).find('.fa-chevron-down'); // 詳細文がなく、アイコンがないcard-headerをクリックした時はundefinedが返されることを利用した if(icon[0] !== undefined) { // thisをつけてクリックした要素にだけ効かせる。そうしないと全部の矢印にtoggleClassが効いてアニメーションしてしまう // findで.fa-chevron-downのついた要素を見つけ、そこにクラスを追加している // spined-iconというクラスでアニメーションをつけている $(this).find('.fa-chevron-down').toggleClass("spined-icon") } }); });また、
spined-icon
がtoggleClass
によって削除されても、fa-cheveron-down
にtransition-duration
を設定することでアニメーションがうまくいった。logs/index.scss// ywtのカードヘッダーに、開閉可能な場合つける矢印 @mixin ywt-header-angle($anglecolor: $second-color) { i.fa-chevron-down { color: darken($anglecolor, 30%); // アイコンのクラスに、transitionをつけることで、閉じる際にもアニメーションを有効化している transition-duration: 0.5s; } } // 矢印のアニメーション用 .spined-icon { transform: rotate(90deg); transition-duration: 0.5s; }おわりに
JavaScriptやjQueryへの苦手意識はまだまだ消えないが、
console.log
で処理や戻り値を追いながら、1つずつ進めていくことで、なんとか実装。
心残りとしては、カードの開閉が可能かどうかをチェックするためのif(icon[0] !== undefined)
について。
if(icon[0] == "<i class=\"fas fa-chevron-down\"></i>")
じゃなぜダメだったのか?
indexOf
が使えなかったのはなぜか?
icon
の中の情報はどのように使うのが正解だったのか?ここらへんに対してしっかり調べて解決することが出来なかったこと。
学習が進み、分かり次第追記予定。
- 投稿日:2020-06-30T20:42:35+09:00
TurbolinksでpushStateするには
JavaScriptでURLを変更し、ブラウザーではページ遷移しないようにするには、history.pushStateを使います。Turbolinksが動いている環境でpushStateを使うと、ブラウザーの進む/戻るで挙動がおかしくなります。Turbolinks以外がpushStateしたときページでは、popstateイベントをTurbolinksが処理しないからです。
Aページ -(pushState)-> Bページ -(リンク)-> Cページ -(戻るボタン)-> URLはBだけど画面が変わらないTurbolinksを使っているときは、次のようにします。
/users?name=Taro
に戻ると、turbolinks:load
イベントが発火するようになります。let path = "/users?name=Taro"; Turbolinks.controller. pushHistoryWithLocationAndRestorationIdentifier(path, Turbolinks.uuid());参考: Manage browser history manually for one part of my Turbolinks-enabled Rails 5 app - Stack Overflow
- 投稿日:2020-06-30T20:02:33+09:00
【Rails】lightbox2を用いて画像拡大機能の実装
目標
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina前提
下記実装済み。
実装
1.
application.html.slim
を編集application.html.slimdoctype html html head title | Bookers2 = csrf_meta_tags = csp_meta_tag = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' / 追記 link href='https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.7.1/css/lightbox.css' rel='stylesheet' = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' / 追記 script src='https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.7.1/js/lightbox.min.js' type='text/javascript'2.
image_tag
を編集books/show.html.slim= link_to @book.image.url, 'data-lightbox': @book.image do = image_tag @book.image.to_s
- 投稿日:2020-06-30T18:29:26+09:00
link_toに情報を付随する方法
前提
- ruby on rails 6.0.0 を使用。
- ファイルの拡張子はhtml.erbである。(haml等を使用している場合は適宜読み替える)
やりたいこと
- link_toメソッドでページを偏移すると同時に偏移先へ情報を受け渡す。
方法
link_toの偏移先情報(urlやpath、モデル等)に渡したい情報を付随する。
index.html.erb<% @tags.each do |tag| %> <%= link_to movies_path(tag_id: tag.id) do %> <%= tag.name %> <% end %> <% end %>上記の二行目にある通り、偏移先情報の後ろに()で渡したい情報を追記すると、ハッシュの形式で情報を付随することができる。
movies_controller.rbdef index @tag = Tag.find(params[:tag_id]) endといったように、偏移先のコントローラではparam[]の形でパラムとして受け取ることで、渡された情報を扱うことができる。
終わりに
基礎中の基礎ではあるが、それゆえに重要になってくる部分でもあるのでしっかりと使いこなしていきたい。
- 投稿日:2020-06-30T18:29:26+09:00
link_toに情報を付随する
前提
- ruby on rails 6.0.0 を使用。
- ファイルの拡張子はhtml.erbである。(haml等を使用している場合は適宜読み替える)
やりたいこと
- link_toメソッドでページを偏移すると同時に偏移先へ情報を受け渡す。
方法
link_toの偏移先情報(urlやpath、モデル等)に渡したい情報を付随する。
index.html.erb<% @tags.each do |tag| %> <%= link_to movies_path(tag_id: tag.id) do %> <%= tag.name %> <% end %> <% end %>上記の二行目にある通り、偏移先情報の後ろに()で渡したい情報を追記すると、ハッシュの形式で情報を付随することができる。
movies_controller.rbdef index @tag = Tag.find(params[:tag_id]) endといったように、偏移先のコントローラではparams[ ]の形でパラムとして受け取ることで、渡された情報を扱うことができる。
終わりに
基礎中の基礎ではあるが、それゆえに重要になってくる部分でもあるのでしっかりと使いこなしていきたい。
- 投稿日:2020-06-30T17:23:45+09:00
Rust は流行りそうもないので、Go を使う。
最近、暇で以下のサービスを作った。
https://deau-project.herokuapp.com/バックエンドには仕事で使ったことがない、Go にした。
勉強してたのは、Rust で、仕事のCSVを分析するシステムを Rust で作ったけど、
この先、使うことがないのでは? と思っている。以前、Haskell が流行りそうで、だいぶ勉強したけど、今では話題にすらならない。
関数型も、いまいち浸透していない。流行る言語は、何かしらの手間を無くす。
Ruby が流行ったのは、Rails がフレームワーク使用時の共通作業を無くしたから。
PHP が未だに廃れないのは、WordPress が共通作業を無くしてるから。Go は流行る。もう流行っている?
理由は学習コストを減らしたから。今回、Go Gin を使用した、そして、簡単に実装できた。
情報も充分にあった。Rust でも、情報に関しては充分にある。
ただ、実装時に面倒だなと感じることが多い。
私のように趣味で実装するなら、尚更、面倒に感じる。Rust が流行るには、組込み系にターゲットを絞るか、
当時の Rails のような手間を省く何かが必要だと思う。
組込み系で考えれば、C++でよくあるミスを防げる。確認の手間を省ける。今回、サーバーサイドに Go を使用したが、この先はどうかわからない。
趣味でならいいが、仕事で使うとなると、関数型である必要がある。
もし、今から新しいシステムを作るとして、サーバーサイドに何を使用すればいいのか。
- 投稿日:2020-06-30T16:55:13+09:00
MySQLの稼働が安定しない…Railsアプリが起動していない。
発生した背景
MySQLサービスがまたもやエラー。何回も発生すると、流石に時間の浪費に怯えてしまいます。以下エラー内容になります。
Can't connect to local MySQL server through socket '/tmp/mysql.sock'環境
項目 内容 OS.Catalina v10.15.4 Ruby v2.5.1 Ruby On Rails v5.2.4.3 MySQL v5.6 対応手順
【調査1】MySQLが起動しているか。
僕は「SequelPro」を使っているので、接続してみる。→接続エラープロセスの稼働状況を確認CMD>ps -ef | grep mysql 501 1287 1 0 11:45AM ?? 0:00.06 /bin/sh /usr/local/opt/mysql@5.6/bin/mysqld_safe --datadir=/usr/local/var/mysql 501 6400 1287 0 11:55AM ?? 0:00.51 /usr/local/opt/mysql@5.6/bin/mysqld --basedir=/usr/local/opt/mysql@5.6 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/opt/mysql@5.6/lib/plugin --log-error=ichikawadaisukenoMacBook-Air.local.err --pid-file=ichikawadaisukenoMacBook-Air.local.pid 501 6402 804 0 11:55AM ttys000 0:00.01 grep mysql!?稼働しているようには見える!?
【調査2】まずはエラー内容から。ソケットファイルがないと言われているので、以下のコマンドで対応してみました。
ソケットファイルを試しに作成してみる。CMD>cd アプリケーションフォルダ CMD>touch /tmp/mysql.sock→結果、改善せず。
【調査3】ログを確認してみる。
MySQLのログを確認CMD>more /usr/local/var/mysql/ichikawadaisukenoMacBook-Air.local.err (一部省略) mysqld_safe A mysqld process already exists※この後再起動するも、改善ならず。
対応
プロセスが多重起動している様子。既存の稼働中のプロセスを停止する。
プロセスの停止CMD>kill -9 対象のサービスプロセス今回はこれだけで改善しました。しかし、まだ以下のエラーメッセージが出力されたままです。
200616 16:04:42 mysqld_safe A mysqld process already exists対応は後日にしようと思います。
- 投稿日:2020-06-30T11:44:34+09:00
モノリスはクラピカ
Reactを学習中のRailsエンジニアです。学習していて思うのは、Reactは(サービス開発全体のことを考えると)Railsよりはるか学習コストが高いということ。似たようなサービスを作るために必要な手数も、考えなければいけないこともかなり多いです。
正直最初は「技術が大好きなエンジニアの自己満だろ」「Railsに飽きた奴らがやってるだけだろ」くらいに思っていたのですが、そうとも限らないことが腹落ちして理解できるようになったので、現在の考えをまとめてみようと思います。
おことわり
この記事の中で登場する
SPA
という単語はフロントエンドとバックエンドを明確に分けて開発されるアプリケーション
くらいの意味として解釈してください。フロントエンドのロジックをNuxt.jsで作ってNetlifyにデプロイして、Goで作ったAPIをAWSで動かす、みたいな構成のやつです。乱暴ですみません。他に良い表現があればコメントください。
モノリス
はRailsやLarabelでviewファイルの生成まで行っているアプリケーションを指します。SPA⇄MPA
マイクロサービス⇄モノリス
で比較しろよ、って話ですが、マイクロサービスについて語れるほどの知識はないし、MPAというよりモノリスの話がしたかったので、雰囲気で読んでください。SPAが台頭した理由
よりリッチな表現ができる(UXの向上)
ページ遷移が高速、DOMを色々動かしてもコードがカオスになりにくいなど。SPAのメリットとして真っ先にあげられることが多いので、みなさんもよくご存知かと思います。
フロントエンドとバックエンドが疎結合になる
疎結合になると、新技術を部分的に採用することが容易になります。またサービスの規模が大きくなっても、コードがカオスになりづらいです。Railsエンジニアをやっていると、成長し大規模化したRailsアプリ開発者がつらそうにしている記事をよく見かけます。
クロスプラットフォーム対応
SPAを採用すると、web、iOS、Android、macOS用アプリ、windows用アプリで同じAPIを使うことができます。
元々web以外のプラットフォームでは、表示周りやページ切り替え等のロジックを先にインストールして、他に必要なデータのやりとりだけをAPIを使って行う、というスタイルで統一されていました。webも同じスタイルに揃うと構成がキレイになってすっきりしますね。マネージドサービスの充実
この記事を書くに至った理由です。この視点を得て、SPAが普及したことの必然性を理解しました。
2020年現在、ざっと思いつくだけでも以下のようなマネージドサービスが存在します。認証: Firebase Auth, Auth0, Cognito
決済: Stripe
検索: Algolia
サーバーレスコンピューティング: Lambda, Cloud Functions
NoSQL: CloudFirestore, DynamoDB
ストレージ: S3
メール送信: SendGridここで言えるのは、バックエンドで自前で実装しなければいけない機能が大幅に減ったということです。
「外部サービスをどれだけ有効に活用できるか」が重要になってくると、モノリスの魅力は相対的に薄れていきます。そもそもRuby on Railsが登場した2004年にはAWSすら存在しておらず、モノリスがwebアプリ開発のど真ん中に鎮座していた2010年代前半にも、上記で紹介したサービスの多くは存在していませんでした。
いくらRuby on Railsも進化しているとはいえ、これだけ状況が変わってしまえば、開発のメインストリームから外れてしまうのは仕方のないことだと感じます。
また余談ですが、Rubyの認証ライブラリで1番人気があるDeviseを使っている人は、全員つらそうな顔をしています。
その他
- コンポーネント単位で分割することで保守性や再利用性が高くなったり、デザイナーとの協業がしやすくなる
- TypeScriptとVSCodeの連携がすごい
などなど他にもSPAのメリットは色々とありそうですが、これらはどちらかというと副産物に近く、SPAが台頭したメインの理由では無いと考えています。
モノリスは用済みになったのか
全くそんなことは無いと考えています。
以下の条件を満たすアプリケーション開発では、今でもモノリスがファーストチョイスです。
「モノリスでも問題ない」ではなく、「モノリスの方が圧倒的に良い」です。
- webだけで良い
- 関わる開発者が少ない
- UXの要件がそれほど厳しくない
具体的な場面としては
- 多くのwebアプリののプロトタイプ
- リリース後の修正が少ないと予想されるシステム
- 機能要件が指定された受託開発など
- 「この機能を削ればこの予算で実現できます」など仕様をモノリスに寄せることで双方が得をする場面は必ず存在する
- 小~中規模のwebアプリの一部
- 必要な要件や、想定されるユーザー数などから技術選定。モノリスの方が効率良く開発できるサービスは、今後もそこそこの割合で残り続けるはず。
などが考えられます。
モノリスの最大の弱点とされる密結合は、必ずしも悪ではないのです。
分割は短期的な生産性を下げます。
密結合は短期的な生産性を上げます。
この点を考慮して技術選定をするべきです。結論
特定の制約の上で、モノリスはもの凄い力を発揮します。
参考
- 投稿日:2020-06-30T11:30:41+09:00
レコードの新規追加時に登録データにMAX+1のIDを付与する方法
Railsでレコードの新規追加をする際に、自動的に独自IDの付与をしたいケースがあると思います。
例えば、my_idフィールドの最大値+1を付与するなど。部屋(room)の名前を登録したときに、独自id = my_id を付与するサンプルを書いてみました。
成功例
def assign my_id = -1 room = Room.find_by(room: params[:room]) if !room.nil? my_id = room.my_id else Room.connection.execute( "INSERT INTO rooms (my_id, room, created_at, updated_at) SELECT COALESCE(max(my_id), 0)+1, '#{params[:room]}', '#{Time.now}', '#{Time.now}' from rooms" ) my_id = Room.find_by(roomr: params[:room]).my_id end redirect_to("/rooms/#{my_id}") endポイントは
- my_idの最大値検索をINSERT文のサブクエリで行い、一回のクエリ発行になるようにすること (排他)
- created_at, update_atに現在時刻を設定すること
- COALESCEでnull対策をすること
失敗例
def assign my_id = -1 room = Room.find_by(room: params[:room]) if !room.nil? my_id = room.my_id else new_room = Room.create( my_id: Room.max(my_id) + 1, room: params[:room] ) my_id = new_room.my_id end redirect_to("/rooms/#{my_id}") end失敗例のほうでは、begin transaction ~ commit transaction の間に
- SELECT文 --> Room.max(my_id)の検索のため
- INSERT文 --> Room.createのため
が発行されるのですが、
複数のクライアントから同時にassignを呼ばれた際に排他が十分でなく
my_idが重複してしまいます本当は
本当は生SQLは発行せずにActiveRecordで記述したいのですが、
いい方法ないですかね?参考URL
INSERT時にカラムの最大値+1を持ってくる
INSERT文と同時にMAX+1を行いたいです。
INSERT時にデータ登録とmaxの発番がしたい
ActiveRecord の find_or_create_by を確実に実行するには
- 投稿日:2020-06-30T10:32:44+09:00
Ruby on Railsでfont awesomeを使う方法
gemfileに追記する
下記をgemfileに追加する。
# font awesome gem 'font-awesome-rails'bundle install
application.cssへ追記する
下記をapplication.cssのコメントの中に追記する。
application.css*= require font-awesomesassのかたは、普通にコメント外のコードを書くところに下記のように記載。
application.scss@import "font-awesome";viewファイルにタグを追加
<i class="fa fa-アイコン名"></i>参考記事
- 投稿日:2020-06-30T09:55:48+09:00
【整理】render&redirect_toが、ごっちゃになってしまうあなたへ
対象者
なんかredirect_toとかrenderとかそれぞれどんな違いあるんだっけ?使い方は?と、知ってるけど頭の中で整理できていない方
前提知識
Railsのコントローラにおけるアクションでは、最終的にrenderされてビューを返す仕組みになっている。
つまり、1アクションにつき、1renderが必ず起こる。def index endこれは、render 'index'が発動していることと同じことである。
エラー例
renderが2回処理されてしまう時
def show ~~ if ~~ ~~ render 'index' end render 'show' end解決策としては、returnをしてあげる
def show ~~ if ~~ ~~ render 'index' return end render 'show' endrender
アクション内で、呼び出すビューを指定するメソッド。
つまり、デフォルトで呼び出されるビュー以外のものを呼び出すことができる。
呼び出すビューの形式は、RHTML形式(.html / html.erb等)
- 同じコントローラの別アクションビューを呼び出す時
microposts_controller.rbdef index render 'edit' render :edit end
- 別コントローラのアクションビューを呼び出す時
microposts_controller.rbdef index render "users/show" render template: "users/show" end
- 別ディレクトリや別アプリのアクションビューを呼び出す時
microposts_controller.rbdef index render "/warehouse_app/app/views/products/show" render file: "/warehouse_app/app/views/products/show" endredirect_to
指定したURLへGETリクエストを送信するメソッド。
つまり、アクション内で発動すれば、再度RCVを呼び出すことになる。
- 指定のページに飛ばす
microposts_controller.rbdef index redirect_to root_url end
- 直前のページに戻す
microposts_controller.rbdef index redirect_back(fallback_location: root_path) end参考にさせていただきました
Railsガイドライン
https://railsguides.jp/layouts_and_rendering.html#render%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B@1ulce様
https://qiita.com/1ulce/items/282cccba1e44158489c8@morikuma709様
https://qiita.com/morikuma709/items/e9146465df2d8a094d78
- 投稿日:2020-06-30T09:26:12+09:00
[�個人アプリ開発]フロント実装の事前準備
はじめに
今回、開発工程のアウトプットはフロント実装の事前準備です。
①hamlの導入、②ルーティングの設定、③コントローラーの設定、④ビューの設定、⑤scssの設定、⑥リセットcssの設定をアウトプットしていきます。hamlの導入
今回開発するアプリのフロント実装にはhamlを使います。(個人的にerbより断然haml派)
まずhamlの使用を可能にする為にgemをインストールします。gem 'haml-rails'その後ターミナルにてbundle installを実行し、ローカルホスト3000を再起動。
#ここで再起動を忘れるとhamlファイルを更新してもエラーが発生するので注意ルーティングの設定
ローカルホスト3000へのリクエストに対してルーティングを設定します。
routes.rbRails.application.routes.draw do root "goals#index" end今回はgoalsテーブルを作成しており、goalsコントローラーのindexアクションを設定しています。
コントローラーの設定とビューの作成
続いてコントローラーを作成します。
ターミナルにてrails g controllerを実行。rails g controller goals indexこれでgoalsコントローラーのindexアクションが設定されました。
この時に以下の2点が追加作成されているかを確認▼①goalsコントローラーにindexアクションが作られている
②viewsのgoalsフォルダにindex.html.hamlファイルが作られている
(#bundle install後に再起動を忘れている場合は、index.html.erbが作成される)この後アプリが正しく動作する為には、予めDBが作成されていないとエラーが発生するので、
以下のコマンドを実行▼rails db:createこれでローカルホスト3000にアクセスするとデフォルトビューが表示されているはずです。
確認しておきましょう。scssの設定
ファイルの拡張子が違うと設定が反映されない為、以下のファイルを編集▼
①app/assets/stylesheets/application.cssの中身を全て消す
②application.cssの拡張子を変更して「application.scss」に変更これから追加する全てのスタイルシートはapplication.scssから@import(パーシャル)を使って読み込みます。
リセットcssの設定
ブラウザによってデフォルトで設定されたcssによって、予期せぬ誤作動を防ぐ為にリセットcssを設定します。
手順は以下の通り▼①app/assets/styleseetsディレクトリにreset.scssファイルを作成しましょう
②application.scssに以下の記述を行い、reset.scssを読み込むようにしましょう。application.scss@import "reset";③リセットcssはYUI 3を使用します。以下のコードを先程作成した_reset.scssに記述します。
_reset.scss/*! * YUI 3.5.0 - reset.css (http://developer.yahoo.com/yui/3/cssreset/) * http://cssreset.com * Copyright 2012 Yahoo! Inc. All rights reserved. * http://yuilibrary.com/license/ */ /* TODO will need to remove settings on HTML since we can't namespace it. TODO with the prefix, should I group by selector or property for weight savings? */ html{ color:#000; background:#FFF; } /* TODO remove settings on BODY since we can't namespace it. */ /* TODO test putting a class on HEAD. - Fails on FF. */ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td { margin:0; padding:0; } table { border-collapse:collapse; border-spacing:0; } fieldset, img { border:0; } /* TODO think about hanlding inheritence differently, maybe letting IE6 fail a bit... */ address, caption, cite, code, dfn, em, strong, th, var { font-style:normal; font-weight:normal; } ol, ul { list-style:none; } caption, th { text-align:left; } h1, h2, h3, h4, h5, h6 { font-size:100%; font-weight:normal; } q:before, q:after { content:''; } abbr, acronym { border:0; font-variant:normal; } /* to preserve line-height and selector appearance */ sup { vertical-align:text-top; } sub { vertical-align:text-bottom; } input, textarea, select { font-family:inherit; font-size:inherit; font-weight:inherit; } /*to enable resizing for IE*/ input, textarea, select { *font-size:100%; } /*because legend doesn't inherit in IE */ legend { color:#000; } /* YUI CSS Detection Stamp */ #yui3-css-stamp.cssreset { display: none; }これでリセットcssの設定は完了です。
最後に
事前準備は以上です。
今後も個人開発アプリの作業工程をアウトプットしていくので、参考にして下さい!
- 投稿日:2020-06-30T07:59:38+09:00
Rails requireメソッドとpermitメソッドについて
※間違いなどありましたらコメントください。
ストロングパラメーター
意図しないデータの登録・更新を防ぐため、特定のキーしか受け取れないようにするもの。
ユーザーに関係するパスワードや名前などの重要な情報を悪意ある変更から守ってくれます。
privateメソッド内に記述するのが一般的です。requireメソッド・permitメソッド
user.controller.rbprivate def user_params params.require(:キー).permit(:カラム名1,:カラム名2,・・・) end・requireメソッド
params内の特定のキーに紐づく値を抽出・permitメソッド
指定したカラム名の値を取得することができるuser.controller.rbprivate def user_params params.require(:user).permit(:name,:email) end上のケースでは、Userモデルに存在するnameカラムとemailカラムの値を受け取ります。
参考サイト
【Ruby on Rails】ストロングパラメータって何なの?
・https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8
【Rails】requireとpermitメソッド
・https://qiita.com/morikuma709/items/2dc20d922409ae7ce216
- 投稿日:2020-06-30T06:33:54+09:00
[個人アプリ開発]データベース設計
はじめに
6/29データベース設計を行いました。その際に取り入れた作業をアウトプットします。
データベース設計流れ
①機能の洗い出し▼
開発アプリの機能を箇条書きで洗い出します。(先日READMEに記述済み)
次に、洗い出した機能にはどういったカラムが必要であるのか選定を行い、各カラムに必要な制約を決める。②アソシエーションを把握▼
ER図を自分なりに書き出し、アソシエーションを把握しておく。③READMEへ記述
最後にマークダウン記法を使用しREADMEへ記述します。#マークダウン記法についてわからない方はこちらのURLを参考にしてください▼
https://www.asobou.co.jp/blog/bussiness/markdown#:~:text=Markdown%EF%BC%88%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%80%E3%82%A6%E3%83%B3%EF%BC%89%E3%81%AF%E6%96%87%E7%AB%A0,%E3%81%AB%E3%82%88%E3%81%A3%E3%81%A6%E9%96%8B%E7%99%BA%E3%81%95%E3%82%8C%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82④データベース設計の記述例
<!-- ユーザー管理機能 --> <!-- usersテーブル --> |Column|Type|Options| |------|----|-------| |id|integer|null: false| |name|string|null: false| |mail|string|null: false, unique: true| |pass|string|null: false, unique: true| <!-- アソシエーション --> has_many :messagesマークダウン記法が反映されると以下のようになります▼
Column Type Options id integer null: false name string null: false string null: false, unique: true pass string null: false, unique: true has_many :goals
最後に
ここまででデータベース設計は完了です。
次回作業工程はフロント実装の事前準備としてルーティング、コントローラー、ビューの設定を行い、Hamlを導入します。
- 投稿日:2020-06-30T02:06:19+09:00
消せいないプロセスID(PID)の消去方法!(Vim、Viでの操作不能の対処)
$ sudo visudoのコマンド入力できなくなり凄く困ったので解決方法を記載します!
何かの不具合で、
.ssh %
の状態もしくは[ec2-user@ip-xx-x-x-xxx] $
から強制終了されるとターミナルでのコマンド入力ができなくなる時があります。私も、過去に似たような経験をしたことがあり、多分プロセスIDが正常に切られなかったため、
ec2-user
にログインした際、$ sudo visudo
が入力できないと予測しました。
発生したエラーは下記ですエラー文visudo: /etc/sudoers がビジー状態です。後で再試行してくださいこの問題を可決するのに凄く時間を費やしたので、プロセスID(PID)の一般的な消去方法とプロセスID(PID)が無限に増殖する際の消去方法について記載したいと思います。
1. 基本のプロセスID(PID)の消去方法!
1. ターミナルでルートディレクトリーに移動する。または、
.ssh %
の状態もしくは[ec2-user@ip-xx-x-x-xxx] $
にする。ターミナルの初期画面の状態xxxxxxxxx@xxxxxxxxxxMacBook-xxx ~ % (例です)2.psを入力する
ルートディレクトリーxxxxxxxxx@xxxxxxxxxxMacBook-xxx ~ % ps.sshxxxxxxxxx@xxxxxxxxxxMacBook-xxx ~ .ssh % psec2-use[ec2-user@ip-xx-xx-xx-xxx ~]$ ps3.PID(プロセスID)が表示されるのを確認する
4.PID(プロセスID)を
kill
orkill -9
で削除する(私はec2-userの状態でエラーが発生したため、ec2-user状態での記載例を載せる)
[ec2-user@ip-xx-xx-xx-xxx ~]$ kill PIDの数値 or kill -9 PIDの数値 [ 入力例 ~] $ kill *** or kill -9 *** (*** = PID)
kill -9 (PID番号)
で入力すると強制的に終了させる事ができる。5.PID(プロセスID)が消去できれば、問題なく動作可能
私の場合、この手順ではPID(プロセスID)の消去ができませんでした。実際に起きていた問題は、PID(プロセスID)を消去しても無限に再生される状態でした。
2. PID(プロセスID)の無限出現の消去方法
ここからが本題です!
私を苦しめたPID(プロセスID)の無限出現です。消し方が分かればすごく簡単に直せます!1. ターミナルでルートディレクトリーに移動する。または、
.ssh %
の状態もしくは[ec2-user@ip-xx-x-x-xxx] $
にする。ec2-use[ec2-user@ip-xx-xx-xx-xxx ~]$ (例です)私は、ec2-user内で発生したので、上記の状態で説明を続ける
2.
ps l
を入力するec2-use[ec2-user@ip-xx-xx-xx-xxx ~]$ ps l3.プロセスごとの実行状態を確認する
4.
WCHAN
の列にあるwait_w
のPID(プロセスID)をkill
で消去するkillやり方[ec2-user@ip-xx-xx-xx-xxx ~]$ kill PIDの数値 or kill -9 PIDの数値 [ 入力例 ~] $ kill *** or kill -9 *** (*** = PID)5.無限増殖するプロセスID(PID)の消去ができたため、無事に入力可能となる!
参考資料
psのコマンドの種類は下記の
ps コマンド集
に記載されてます。
もし、ご興味がありましたら見て下さい!
ps コマンド集最後に
以上で、消せいないプロセスID(PID)の消去方法(プロセスID無限増殖)の説明を終わりたいと思います。間違っているてん、不明点があればご指摘頂けると助かります。
最後までご覧いただき、ありがとうございました。
- 投稿日:2020-06-30T02:06:19+09:00
消せないプロセスID(PID)の消去方法!(Vim、Viでの操作不能の対処)
$ sudo visudoのコマンド入力できなくなり凄く困ったので解決方法を記載します!
何かの不具合で、
.ssh %
の状態もしくは[ec2-user@ip-xx-x-x-xxx] $
から強制終了されるとターミナルでのコマンド入力ができなくなる時があります。私も、過去に似たような経験をしたことがあり、多分プロセスIDが正常に切られなかったため、
ec2-user
にログインした際、$ sudo visudo
が入力できないと予測しました。
発生したエラーは下記ですエラー文visudo: /etc/sudoers がビジー状態です。後で再試行してくださいこの問題を可決するのに凄く時間を費やしたので、プロセスID(PID)の一般的な消去方法とプロセスID(PID)が無限に増殖する際の消去方法について記載したいと思います。
1. 基本のプロセスID(PID)の消去方法!
1. ターミナルでルートディレクトリーに移動する。または、
.ssh %
の状態もしくは[ec2-user@ip-xx-x-x-xxx] $
にする。ターミナルの初期画面の状態xxxxxxxxx@xxxxxxxxxxMacBook-xxx ~ % (例です)2.psを入力する
ルートディレクトリーxxxxxxxxx@xxxxxxxxxxMacBook-xxx ~ % ps.sshxxxxxxxxx@xxxxxxxxxxMacBook-xxx ~ .ssh % psec2-use[ec2-user@ip-xx-xx-xx-xxx ~]$ ps3.PID(プロセスID)が表示されるのを確認する
4.PID(プロセスID)を
kill
orkill -9
で削除する
(私はec2-userの状態でエラーが発生したため、ec2-user状態での記載例を記載します)[ec2-user@ip-xx-xx-xx-xxx ~]$ kill PIDの数値 or kill -9 PIDの数値 [ 入力例 ~] $ kill *** or kill -9 *** (*** = PID)
kill -9 (PID番号)
で入力すると強制的に終了させる事ができる。5.PID(プロセスID)が消去できれば、問題なく動作可能
私の場合、この手順ではPID(プロセスID)の消去ができませんでした。実際に起きていた問題は、PID(プロセスID)を消去しても無限に再生される状態でした。
2. PID(プロセスID)の無限増殖の消去方法!
ここからが本題です!
私を苦しめたPID(プロセスID)の無限増殖です。消し方が分かればすごく簡単に直せます!1. ターミナルでルートディレクトリーに移動する。または、
.ssh %
の状態もしくは[ec2-user@ip-xx-x-x-xxx] $
にする。ec2-use[ec2-user@ip-xx-xx-xx-xxx ~]$ (例です)私は、ec2-user内で発生したので、上記の状態で説明を続けます。
2.
ps l
を入力するec2-use[ec2-user@ip-xx-xx-xx-xxx ~]$ ps l3.プロセスごとの実行状態を確認する
下記のような画面が表示されると思います
4.
WCHAN
の列にあるwait_w
のPID(プロセスID)をkill
で消去するkillやり方[ec2-user@ip-xx-xx-xx-xxx ~]$ kill PIDの数値 or kill -9 PIDの数値 [ 入力例 ~] $ kill *** or kill -9 *** (*** = PID)5.無限増殖するプロセスID(PID)の消去ができたため、無事に入力可能となる!
参考資料
psのコマンドの種類は下記の
ps コマンド集
に記載されてます。
もし、ご興味がありましたら見て下さい!
ps コマンド集最後に
以上で、消せないプロセスID(PID)の消去方法(プロセスID無限増殖)の説明を終わりたいと思います。間違っている点がありましたらご指摘頂けると助かります。
最後までご覧いただき、ありがとうございました。