【Rails】paramsがなんなのかやっとわかった!
こんにちは、マリンです。
Railsでform
とか使っていれば当然params
って出てきますよね。
恥ずかしながら、このparams
の認識が違っていたために職場でかなり苦労しました。
やっと見えてきたのでまとめようと思います。
*内容に間違いや補足などございましたら、是非ともご指摘ください!
paramsとは?
params
メソッドとは、URLから送られてくる情報を受け取るメソッドです。
初っ端ですが、私の認識はここが間違っていました。
DBのレコードが持つ情報やカラムに紐付いた情報を表していると思っていました。
なんでこんな誤解が生まれたかはちょっと謎ですが・・・
まぁ、教材を流し読みしたせいだと思います。
とにかく、param
はURLからの情報を受け取るメソッド。
このことがわかれば、これまで職場で???となっていた全ての現象の辻褄が合いました。
paramsで受け取れるもの
formの値
まずは言わずと知れたform
から送られてくる値ですね。
<%= form_for @user do |f| %> <%= f.text_field :name %> <% end %>
@user = User.find_by(name: params[:name])
form_for
で入力された:name
を元にユーザーを探し出してます。
ここまでは良かったのですが、これがform_tag
に成った時に一気に躓きました。
<%= form_tag hoge_hoge_path do %> <%= password_field_tag 'password_text', ' ' %> <% end %>
@password = params[:password_text]
ただ入力されたパスワードを変数に入れてるだけなんですけど、
私はparams
で扱えるのがDBのカラムにあるものだけだと思っていたので、
ここで混乱するわけですね。
「password_textなんてカラムないけど!?」と。
なんともお恥ずかしい話です。
何はともあれ、URLからの値を受け取るので当然このように使用することが可能です。
クエリパラメータ
クエリパラメータとはURLに付け加えられたページの情報です。
http://hogehoge/hugahuga/hello?name=marin
この?
以降がクエリパラメータです。
params
ではこの値も受け取ることができます。
この場合はlink_to
からの値ということになると思います。
<%= link_to "marin", hogehoge_hugahuga_path(name: 'marin')
@user = User.find_by(name: params[:name])
こんな感じでしょうか。
番外 〜ストロングパラメータ〜
なんか悪い人からの攻撃に対応するために扱う値を制限するってやつですね。
チュートリアルとかでもやってるんですが、多分ここが私の誤解の原点ではないかと思います。
params.require(:user).permit(:id, :name, :email)
こんな感じのやつですね。
users
テーブルのid``name``email
は扱えますよと言っています。
(多分ここでテーブルに関連する値しかparams
は使えないと勘違いしたのではと)
大体の場合は
def hugahuga @user = params(user_params) end private def user_params params.require(:user).permit(:id, :name, :email) end
という感じで使うのではないでしょうか?
まとめ
そういえば、form
ではhidden_field
なんてのに渡した値を取得する場面もありました。
自分のどこが理解できていなかったのか?何を間違えているのか?
それがわかれば本当はもっと簡単にコードが読めるのかもしれません。。。
わからない時には一度立ち止まって、
つまづいている部分がどこなのかを見極めるのも大事ですね。
【Rails】なんか変なとこのヘルパー読み込んでるんだけど??〜config.action_controller.include_all_helpers〜
こんにちは、マリンです。
昨日こんなことがありました。
「staffのネームスペースでuserのhelper読み込んでるんです・・・」
その時に教えていただいた対処法をご紹介します。
概要
app/helpers/user/pages_helper.rbに
hoge
と言うメソッドがあった。同じ処理を行いたいのでapp/helpers/staff/pages_helper.rbにも
hoge
と言うメソッドを書いた。app/controllers/staff/staffs_controller.rbからネームスペースstaffの
hoge
を呼び出した。(つもり)なぜかネームスペースuserの
hoge
が呼ばれてしまう!?
こういった経緯で自己解決できずに相談しました。
原因
Railsのcontrollerでは、デフォルトで全部のhelperを読み込むようになっているそうです。
なので意図しないファイルを読み込んでいる場合は、
キチンとネームスペース内のものだけを読み込むように設定しないといけないとのこと。
対処方法
config/application.rbファイルに以下を記述します。
config.action_controller.include_all_helpers = false
これはデフォルトで全てのヘルパーを読み込むようになっているのを、
「やめて〜〜!!」
と言っています。
これでネームスペースに則ったヘルパーのみを読み込んでくれるようになるということです。
基礎を勉強するだけではわからないこと、
気付けなかったこと、ぶち当たらなかった壁をたくさん経験できて、
やはり一歩踏み出して良かったな。
と感じる今日この頃です。
【Rails】remote: trueでサクッと画面切り替え
こんにちは。マリンです。
数ヶ月ぶりの更新となってしました。今まで何をしていたかと言いますと・・・
アルバイト先で修行しておりました。否。「おります」進行形です。
でもちょっとだけ余裕ができたので、これまでに学んだことを少しずつここで残せたらと思います。
まず最初は、「空気のごとく使えるようになること!」と言われたremote: true
についてです。
*内容に間違いや補足などございましたら、是非ともご指摘ください!
remote: trueとは
そもそもremote: true
とは?
それはAjaxを使って画面を切り替えることができる機能です。
(Ajaxについてはこちらの記事でわかりやすく説明して下さっています。
つまり、通常ではまるっとページ全部を読み込んで画面遷移するところを、
その部分だけ差し替えて画面を切り替えてしまおうってことですね。
remote: trueの使い方
では本題の使い方です。
バイト先でよく使った登録フォームを例にとって説明します。
「新規登録」のリンクをクリックすると、登録フォームがremote: true
で表示されるようにします。
index.html.erb
Ajax切り替え用のremoteオプションと、
中身を差し替える部分にid
を用意します。
remoteオプションは色んなところで使えますが、今回はlink_to
につけます。
app/views/users/index.html.erb
<%= link_to "新規登録", user_new_path, remote: true %> <div id="samplRemote"></div>
Ajaxへの切り替え処理はこれだけです。
new.js.erb
お恥ずかしいことにコントローラが探しに行くテンプレート
(というかviewsに置けるファイル)って、
〜html.erbだけだと思っていました。
でも本当はjsとかもあるんですね・・・
remote: true
の場合はまずこちらを探してもらって、
このjsファイルの中でrender
を使って_new.html.erb
を呼び出します。
app/views/users/new.js.erb
$('#samplRemote').html("<%= escape_javascript(render 'new') %>");
対象のid
はindexの差し替える部分につけたid=samplRemote
です。
.html
で_new.html.erb
を読み込むよう、
要素を書き換えています。
_new.html.erb
ページの中身はパーシャルとして_new.html.erb
の中に書きます。
app/views/users/_new.html.erb
<%= form_for @user do |f| %> # フォームの中身 <% end %>
これでAjaxを使った画面の差し替えが完了です。
コントローラは通常通りのnew
やcreate
で大丈夫です。
remote: trueが使えるもの
最後に、このremote
オプションが使えるものです。
form_for
form_tag
link_to
button_to
他にもあったら是非教えてください。
まとめ
まだまだちゃんと学ぶと奥が深そうなremote: true
ですが、
今はとりあえずこんな感じで使えるようになりました。
ロード時間の短縮にもなるし、サーバーへの負担も軽減されるし、
大変ありがたい機能ですね!
【rails】ページごとにCSSを当てたい。
こんにちは、マリンです。
知人に頼まれてHTML、CSS、JSのみの完全静的Webサイトを作ったのですが、
このたび機能追加に伴いRails化することにしました。
それまでのコードはペペッと貼り付けてちょこちょこっと修正すればいっかなぁ〜
なんて軽く考えておりましたが、そこはさすがプログラミング。
そう甘くはないですよねぇ・・・
まだまだ色々試行錯誤中ですが、ひとまず今回解決しました、
CSS周りの適用の仕方を書きます。
私はcustom.scssしか知りません
Rails Tutoialでは、それぞれのスタイルを順番に読み込むのは大変!
ということでcustom.scssのみでスタイリングしておりました。
しかし今回、ページごとにスタイルをつけてしまったんですよね。
ダブってるスタイルを別々にし直すのも手ですが、
できればそんな面倒なことはしたくありません。
そこでこちらでもやはり分けた部分はそのまま分けることにしました。
ここで問題になるのは、
これまでごっそりスタイル当ててたcustom.scssしか知らないということです。
個別にスタイルを当てる方法を知らなかったんですね。
問題1:適用の仕方
もちろん最初そのままのコードを使っていましたから、
Viewでの指定の仕方が
<link rel="stylesheet" href="stylesheets/home.css">
なんてことになっていました。
当然うまくいかないわけで、
そこで思い出したのがapplication.cssにあるアレでした。
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
あ。これだ!と思ってapplidation
の部分をhome
に変更してみました。
問題2:precompile
assets.rb
上記だけで実行しようとすると次のようなエラーが出ます。
ActionView::Template::Error (Asset was not declared to be precompiled in production. Add `Rails.application.config.assets.precompile += %w( home.css )` to `config/initializers/assets.rb` and rest art your server):
注意された通りなんですが、
config/initializers/assets.rb
にある
Rails.application.config.assets.precompile += %w( home.css )
この一文のコメントアウトを外して、
( )の中に対象となるCSSなどのファイル名を入れます。
precompile
これでもまだ不十分です。
再読み込みしても同じエラーが出ると思います。
更新を反映させるためにはプリコンパイルが必要になります。
ターミナルで以下の処理を行ってください。
$ rails assets:precompile # もしくはrake assets:precompile
最後にサーバーを再起動させれば完了です。
*これをお忘れなきよう。私は数分困惑しました・・・
まとめ
ここまでやってきた処理は、
「Asset Piplineのコンパイル対象を追加する」という作業になるそうです。
へぇ〜と流してきたAsset Piplineですが、いい機会なので勉強してみてもいいかもです。
とはいえ、これやるとページの読み込みが遅くなるようなので、
やはりスタイルなんかは一つのファイルにまとめた方が良さそうです。
今回はこちらを参考にさせていただきました。
RSpecを学んでいて気付いた自分の弱点。
こんにちは、マリンです。
この度アルバイト先が決まりまして、その会社で「RSpec使ってるから勉強しといて」と言われて今学んでおります。
今回の記事はただのぼやきです。すみません。
今回のテーマ
タイトルの通りです。
RSpecを勉強していて自分の決定的に足りない部分を見つけました。
RSpecについてはいろいろとサイトを巡って情報を集めており、
基本的な書き方は覚えました。
なので以前勉強したRails Tutorialを、今度はRSpecを使ってやってみようと思い立ったのですね。
だがしかし、全っ然出来ないんですよ!
テストが苦手なことは気づいていました。
正直、自分で楽しくやっていた時はスルーしてました。
でもまさかヒントがあるのに書けないとは・・・
そこで自分の最大の弱点に気づいたんです。
私の弱点
ズバリ、「応用力」です。
これが決定的に欠けています。
いや、数学がめっきりダメだった中学の頃から知ってはいたんですけど・・・
なんでテストが書けないかって考えてみると答えは簡単。
アプリ自体は結構そのまま使えたり、ほんのちょっと変えれば使えるようなコードが結構出てくるんですよね。
でもそれについてのテストコードまでは載ってないんです。
だから検索して出てきたコードを参考に自分のサイト作ったりはできますが、
それに対するテストは自分で考えなきゃだからできないんですね。
チュートリアルで基本は学びましたが、
そこから発展していざ自分で考えるとなると・・・
「え?どうすればいいんだっけ??」
となってしまうわけです。
で、どうすんの?
とはいえこのままでは使い物になりません。
そこで、なんで基本は学んだのに自分で考えて書けないのか?を考えてみました。
もちろん応用力が足りないからなんですけど・・・
その応用力に必要なものはなんだ?ともう一歩踏み込んで。
多分、「問題の本質を理解しているか?」だと思います。
目の前にある「〇〇をテストする」ということばかり考えて、
「え?どうやるの??」ってなっているから進まないのだと思うんですよね。
必要なのは、
「〇〇をテストする」
- 〇〇はどうやって動いているのか?
- どの部分をテストすれば良いのか?
- そのテストには何が必要なのか?
といった、〇〇という対象に対してもっと噛み砕いて構造や振る舞い、必要なものを考えないから、
何をしていいのか?がわからないんだと思いました。
前に勧められて読んだ本に書いてありましたが、
問題を解決するには、いかに噛み砕いて問題の本質を理解するかが鍵だそうです。
とはいえ・・・これ今から鍛えて間に合うのか???
と焦っています。
そしてそもそも圧倒的に足りない情報量・・・
どうしよう。
情報収集もしたいし、でもまだ基礎も完璧ではないし、
そして応用効かないし・・・
中学高校と「数学ムリ〜ww」とかヘラヘラしていた自分を呪います。
【Bootstrap4】navbarを2段にしてみた。
こんにちは、マリンです。
大変おひさしぶりになってしまいました。
いろいろと仕事獲得のために動いてまして・・・
つまり何も進展がなくて書くことがなかっただけです。
今回「既存のHPを自由にレスポンシブしちゃって!」と言うとある課題を頂きましたので、
その時に行った表題の件です。
概要
基本、ホームページのスタイリングにはBootstrap4を使っております。
デフォルトのnav
ですが、ご存知の通りnavbar-brand
含め左寄せです。
これを画面の幅に合わせて、
広い時はロゴを上段、ナビを下段。
狭い時はインラインにしたいと思いました。
ついでにナビを中央揃えにします。
navbarを2段にする
float: none;じゃ上手くいかない!
いろいろ調べたのですが、Bootstrap3でのやり方ばかりで4の情報がなく、
それでは上手くいかなくて困り果てた挙句、本家のソースを見に行きました。
問題はこいつです!
display: flex;
Bootstrap3まではfloat
で位置を指定していたので、
float: none;
でできたようなのですが、
4からはこのdisplay: flex;
を使っているのでこいつが使えないのですね。
display: flex;とは?
CSS3から導入されたレイアウトモードです。
これまでfloat
などを使ってコンテンツをレイアウトしていたものを、
より柔軟に、かつ簡単にレイアウト出来るようになりました。
そしてレスポンシブデザインでも便利そうです。
詳しくはこちらをご覧ください。
まだ対応していないブラウザもあるようなのでご注意ください!
navbarを2段にする方法
では本題です。
1. クラスを追加する
スタイルの上書きのためのclass
を追加します。
追加するのはナビの一番の親に当たる<nav>
です。
<nav class="navbar navbar-toggleable-md navbar-light bg-faded gnav">
最後のgnav
がそれです。(名前は任意)
2. スタイルを上書きする
追加したクラスにスタイルをあてます。
.gnav { flex-direction: column; }
flex-direction : カラムをどの方向に並べるかを指定するプロパティです。
column : 文を改行した時に向う方向に並べます。わかりにくですが、通常上から下です。
値については他にもいろいろあるので調べてみてください。
以上です!
長い時間ハマったのが馬鹿みたいなくらい簡単でした・・・
詳しくはこちらをご覧ください。
http://scene-live.com/page.php?page=57
navを中央揃えにする
無事2段にはできましたが、
このままでは「ロゴが中央なのにナビは左寄せ」
という現象が起きます。(理由は後ほど)
なのでナビを中央揃えにします。
1. ul
の幅を100%にする
ナビのリストを囲っているul
の幅を100%にしてください。
ul { width: 100%; }
これをやらないとこの後の処理をいくらやっても真ん中に入ってくれません。
2. クラスを追加する
中央寄せにするためのclass
を追加します。
<ul class="navbar-nav navbar-justified">
最後のnavbar-justified
がそれです。(名前は任意)
3. スタイルを上書きする
追加したクラスにスタイルをあてます。
.navbar-justified { justify-content: center; }
justifiy-content : コンテンツの横方向の位置を指定するプロパティです。
center : 中央揃えにします。
このほかに均等配置にするspace-between
などいろいろあります。
詳しくはこちらをご覧ください。
http://scene-live.com/page.php?page=59
これで無事に完了です!
ロゴが中央なのにナビは左寄せ
前にお話ししたこれです。
原因は2つあります。
原因1 : navbar-navにはコンテンツの配置指定がない
親の.navbar
にはデフォルトでjustifiy-content: space-between;
が指定されています。
しかし<ul>
についてるクラスのnavbar-nav
にはついていません。
そのため、<ul>
の範囲外のnavbar-brand
であるロゴは中央配置になったのですね。
原因2 : ulの幅
原因1に気づいて一生懸命指定しましたが、最初うまくいきませんでした。
そこでデベロッパーツールで見てみると、
<ul>
が左に寄って、かつ幅が狭かったのです。
その幅の中で真ん中にはなっているけど、
そもそもの幅が狭かったせいで全体の中央にこなかったのですね。
まとめ
今回は本当に良い勉強になりました!
何よりも、今までちんぷんかんぷんだった本家のソースとか見ちゃってる自分に感動ですw
でもフレームワークを使用する場合、
思ったようにならない時は元のソースを見ることも必要ですね。
補足
最終的なコードを載せておきます。
ただしこの記事を書いた当時のコードが残っていなかったことと、
Bootstrapのバージョンが上がったことで多少当時と変わっています。
付け焼き刃で急いで試したもので、改善が必要な点が多々あります。
後述しますのでそちらの注意もご覧ください。
<補足時の動作環境>
Rails5
Bootstrap 4.1.1
<ソースコード>
<nav class="navbar navbar-expand-lg navbar-light bg-light" style="flex-direction: column"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="#">Disabled</a> </li> </ul> </div> </nav>
<変更点>
記事ではnav
とul
にクラスをつけて、それぞれ2段にするスタイルと、
中央寄せにするスタイルをつけましたが、Bootstrap4.1.1で試したところ、
nav
に直接スタイルをつける方法でないとflex-direction: column
が効きませんでした。
おそらくnav
についている.navbar-expand-lg
と言うクラスのflex-direction
が優先されているからと思われます。
!important
でいけるかと思いましたが、私の環境ではうまくいきませんでした。
次にul
の方ですが、今回試したところわざわざ中央寄せのスタイルを書かなくても、
自動的に真ん中に寄ってくれました。
なので今回は削除してあります。
<注意点>
上記のコードでは画面を小さくした時のハンバーガーまで
2段の中央寄せになってします。
また、コンテンツの位置を手軽に設定できる
justify-content-~
が使えると便利かと思ったのですが、
そちらは効きませんでした。
これらの改善点も一緒し修正したかったのですが、
まずは早急に補足を書きたかったので至らない点が多々あり申し訳ありません。
またいろいろと試してみてきちんと記事を書こうと思います。
binって何?railsとrakeって何??(後編)
こんにちは、マリンです。
前回はよく見かけるbin
とは何か?
そして、bin/rails
ファイルの中で行われていることが何か?を書きました。(今思えばちょっと趣旨がずれたかも・・・)
今回は、bin/rake
は何か?そしてrails
とrake
の違いなどを書けたらなと思います。
前回の記事はこちらです。
song-of-life.hatenablog.com
bin/rake
とは?
まずは定番のRailsドキュメント様から。
Rakeとは Rubyで記述されたビルドツールです。
1行wwまぁそうなんでそうなんですけど・・・
ビルドツールとはソースコードを実行ファイルに変換したりするプロセスをやってくれるやつですね。コンパイルとか。
UNIX系でよく使われるという「make」がそれです。こっちはRubyだから「Rake」。
自分初心者なんで横文字の用語とかについてくのも必死なんですが、こういう語源とかにも何か大層な意味があるんじゃないかって気になっちゃうんですけど、意外と「え。そういうこと??」みたいのいっぱいありますよね(笑)
話しを元に戻しまして、つまりRakeはRubyで書かれた様々なタスクを呼び出して実行できる機能です。
で、問題はその「様々なタスク」に何があるのか?ですよね。
それはこちらのコマンドで確認できます。
$ rake -T
代表的なものがRailsドキュメントの解説にありますので見てみますと、
載っているのはrake db:migrate
やrake db:rollback
、rake db:seed
、rake about
、rake doc:app
、rake rails:update
、rake db:create
などなど・・・
とってもたくさんありますが、何かデータベース系をいじるものが多い気がします。
他にもいっぱい載ってるんで見てみてください。
rails
とrake
の違い
前述した通り、rake
の説明としては「Rubyで記述されたビルドツール」ということでした。
でrails
については、
アプリケーションに最低限必要なフォルダやファイルを自動的に作成
と書かれています。
何となく「タスクを実行する」っぽい感じは似てる気がしますが、その処理する分野が違うのかな?って感じです。
多分、そういうことではないかと・・・曖昧ですみません。違ってたらご指摘ください。
rake
がrails
に統合されてる
これですね。
Rails5からrake
タスクがrails
コマンドに統一されたそうです。ということで、今後はbin/rails
一本で行けるということですかね。
紛らわしくなくて良いと思います!
ちなみに、Rakeのコマンドに入っていたrake doc:app
とかrake doc:rails
なんかのドキュメント作成系のタスクは削除されたそうです。
Ruby on Rails 5.0 リリースノート | Rails ガイド
bin/がついたりつかなかったり
bin
に戻ってきました。そもそもこれが原因で調べ始めたんですよね。
このbin/
がついたりつかなかったりする現象については、こちらの記事で詳しく説明されていました。
qiita.com
どうやら4.1から標準装備になったSpringというものが関係しているようですね。
これまた調べ始めると長くなるので省略しますが、どうやらサーバの起動が早くなるようですね。
詳しくはこちらの記事をどうぞ。
Railsの開発効率をあげる - Springを使ってRailsのコンソールコマンドの実行を早くする - Rails Webook
Rails4.1 から入ったSpringって何よ? - kasei_sanのブログ
で最初の記事で検証されていたのは、それぞれのコマンドでbin/
をつけた時とつけなかった時のSpringの状態がどうなっているか?ということです。
結論から言うと、rails
コマンドではなくてもOK!rake
コマンドはないとダメ!ということでした。
Railsはbin/rails
ファイルを優先的に起動する仕様になっているけど、bin/rake
ファイルについてはbin/
をつけないと素のrake
コマンドが実行されてしまい、rake -T
とかはSpringを使わないからRailsが起動するまで待たなきゃいけないよ。
ということらしいです。
つまり、bin/rake
ファイル内の処理を実行したい時はつけなきゃいけないんですね!「/」が入ってるからディレクトリの構造を示してはいるんだろうけど・・・とは思っていましたが、スッキリ。
で一つ前の項に書きましたが、Rails5では両者が統一されましたので、5以降を使用する場合はbin/
もいらないし、rails
一本だけでどちらのタスクも使えますよ!ということですね!!
はぁ〜!長かったけどやっとスッキリしたぁ!
ということで、長々とご覧いただきありがとうございました。
内容に間違いがございましたら是非ご指摘ください。よろしくお願い致します!