M1macでrbenvを使ってrubyのインストール
% rbenv install 2.6.3
などrubyのバージョンをインストールしたいときにBUILD FAILEDが出てしまってインストールできないことがある。 そんなときはこれ!
% RUBY_CFLAGS=-DUSE_FFI_CLOSURE_ALLOC rbenv install 2.6.3
なんかわからないけどインストールできる。神
errorメッセージを個別で出したい
色々と調べながらやってるうちに知らない間にerrorメッセージを出せるようになってしまったが、やったことに自分の頭がついていっていないので、落ち着いてまとめてみる。
エラーメッセージ用のテンプレートの作成
まずはじめに全てのエラーメッセージを配列で取得します。が、エラーメッセージ用の部分テンプレートを作成するのが先です。いろいろなところで使うので、viewに書き込むと直すのが手間になってしまいます。views/shared/_error_messages.html.erb
としておきましょう。
<% if model.errors.any? %> <div class="alert alert-warning"> <ul> <% model.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %>
さて、上のように書くことで、エラーメッセージを配列で取得でき、複数のエラーメッセージがある可能性がある(自分で作っていれば)ので、eachを使って、全て取得します。一行ずつ丁寧にみていきます。
- エラーメッセージ用のテンプレートの作成
- 1行目 <% if model.errors.any? %>
- 4行目 <% model.errors.full_messages.each do |message| %>
- 参考
1行目 <% if model.errors.any? %>
<% if model.errors.any? %>
errors.any?
はエラーがあるかどうかの真偽を出してくれるメソッドです。じゃあ、model
は?というと、呼び出す先で指定しているものになります。呼び出し先をviews/users/new.html.erbとでもしましょう。
<%= form_with model: @user, local: true do |f| %> <%= render 'shared/error_messages', model: f.object %> ...
<%= render 'shared/error_messages', model: f.object %>
の部分で呼び出しをしていて、model: f.object
のmodel
の部分が、<% if model.errors.any? %>
のmodelと対応しています。では、f.object
ってなんだろう?ということで調べていきます。
model: f.objectとは
f
はフォームビルダー変数といい、
<%= form_with model: @user, local: true do |f| %>
form_with
で生成された|f|
の部分です。このフォームビルダー変数には様々なメソッドがあり、text_field
(一行のテキスト投稿フォーム)やselect
(選択肢を作成)など様々ある。f.object
には、入力したデータが入っています。つまり、model: @user
の情報をもっていることになるので、userコントローラーのnewアクションとつながっていることになる。かなり遠いところまで行くけど、そういうことみたい。
4行目 <% model.errors.full_messages.each do |message| %>
まず、はじめのmodel
には、呼び出し先の
<%= form_with model: @user, local: true do |f| %>
の@userが代入されます。そして、errorsメソッドで@userの持っているエラーを表示してくれ、full_messages
でエラーの文章のみを配列で表示してくれます。そして、each do |message|
でエラーの配列を一つ一つ処理してくれる、というようになっているようです。
これでエラーメッセージが個別で出る動きが分かった。難しい。
参考
https://yama2-0506.hatenablog.com/entry/2020/12/11/083007 https://qiita.com/ryuuuuuuuuuu/items/1a1e53d062bff774d88a
Railsでデータベースのリセットをしよう!
データベースを空にするために、
rails db:reset
と
rails db:migrate:reset
の2種類存在する。この2つについて考えていきます。
rails db:resetとは
rails db:reset
は2種類のコマンドを実行するのと同じ働きがあります。
上の2種類のコマンドを実行するのと同等なので、一度データベースを削除して、スキーマからテーブルを再度作成し、シードデータを用いてデータベースの初期化を実行します。
rails db:migrate:resetとは
rails db:migrate:reset
では、DBの削除、DBの作成、rails db:migrate
が行われます。なので、seeds.rbの読み込みがないため、ダミーデータのようなものは作成されません。
どちらを使うか
seeds.rbの読み込みまでしたい場合は、rails db:reset
読み込みまではしたくない場合は、rails db:migrate:reset
ということになる。
参考
https://k-koh.hatenablog.com/entry/2020/09/25/232829 https://railsguides.jp/active_record_migrations.html https://note.com/kentarotawara/n/n976705aa4cb8 https://railsdoc.com/rake#rake_db_migrate
はてなブログでMarkdownで目次が作りたい!
ということで、Qiitaとかみてると目次ってかっこいいなと、思うわけですよ。なので、今回は目次について調べて、実際に使ってみようと思います!
はてなブログを参考に
まず、目次を挿入したい行に[:contents]
と記入をする。
[:contents]
その下に見出しをつけてやればできるらしい。
できてる。
#の数で入る場所が変わるぜ
面白い。
参考
buildメソッドって?
インスタンスを生成するメソッド。モデルの関連付けでも用いられる。
newメソッド
と同じ使い方をするが、モデルの関連付けの際には、暗黙のルールとしてbuildメソッド
を使う。
buildの記述方法
全部で3パターン。モデルの同士の関連付けで変わってくる。 1. アソシエーションが1対1 2. アソシエーションが1対多 3. アソシエーションが多対多
1対1の場合
ユーザーが予定を1つ持っている場合として、
class User < ActiveRecord::Base has_one :plan end
class Plan < ActiveRecord::Base belongs_to :user end
このような1対1関係では、build_関連付けのメソッド名
となります。
@user = User.new @plan = @user.build_plan
1対多の場合
ユーザーが予定を複数持っている場合として、
class User < ActiveRecord::Base has_many :plans end
class Plan < ActiveRecord::Base belongs_to :user end
このような1対多関係では、関連付けのメソッド名.build
となります。
@user = User.new @plan = @user.plans.build
多対多の場合
多対多の場合中間テーブルを作るため、以下のようにモデルを作成します。
class User < ApplicationRecord has_many :group_users has_many :groups, through: :group_users end
class Group < ApplicationRecord has_many :group_users has_many :users, through: :group_users end
class GroupUser < ApplicationRecord belongs_to :group belongs_to :user end
このような多対多関係では、1対多と同様に関連付けのメソッド名.build
となります。
@user = User.new @group = @user.groups.build
buildでも場合分けするので覚えなければ!
参考
form_withって難しい(n回目)
form_withっていろいろな情報があって、何が何やらさっぱりなので、少しまとめて行きたいと思います。たくさん参考にしながらやっていきます。
form_tagとform_for
まず、form_withは第一引数にmodel:かurl:を使います。この使い分けは、
<%= form_with url: "パス" do |form| %> フォーム内容 <% end %>
<%= form_with model: モデルクラスのインスタンス do |form| %> フォーム内容 <% end %>
なぜ、この2つに分けられているのかというと、もともとform_with
はform_tag
とform_for
が使われていました。form_tag
は保存する必要がない時、form_for
は保存する必要があるときに使います。
<%= form_tag('/main', method: :post) do %> <input type="text" name="nickname"> <input type="submit"> <% end %>
<%= form_for(@user) do |f| %> <%= f.text_field :name %> <%= f.submit %> <% end %>
form_tag
とform_for
で書き方が異なることが分かります。form_for
では、FormBuilderオブジェクトのヘルパーメソッドを使っています。FormBuilderオブジェクトとは、上の例だとform_forというヘルパーメソッドの引数である@userの情報を持っている「f」です。フォームを作るときに便利なヘルパーメソッドを使うことができます。form_forによって作られるオブジェクトということなのかな?text_fieldやsubmitなど便利なヘルパーメソッドを使えます。
form_withとは
form_tag
とform_for
くっつけたらもっと簡単なのになー。モデルでもパスでもどっちも使えたらなー。ということで、form_with
が誕生したらしいです。
使い方をもう一度
<%= form_with model: @user do |form| %> フォーム内容 <% end %>
<%= form_with url: root_path do |form| %> フォーム内容 <% end %>
form_with
でmodelオプションを使う場合は、引数にモデルクラスのインスタンスを指定します。モデルクラスのインスタンスとは、保存したいテーブルのクラスのインスタンスのことをいうそうです。よく分かりません。
進めます。usersテーブルに新たにレコードを作成したいので、コントローラーに
def new @user = User.new end
と記述します。この@userがform_withの引数に指定されるのです。@userが新規に作成された場合(@userになんの情報も入っていない)には、createアクションへ、@userにすでに情報が入っている場合にはeditアクションへ自動的にform_withが振り分けてくれます。
参考
https://pikawaka.com/rails/form_with https://qiita.com/kenkentarou/items/f6b2f033d8b14056ec81
部分テンプレートをrenderするときのcollectionってなに?
部分テンプレートをレンダリングするときに、ローカル変数を渡す時があるけれど、何種類も渡し方があるので、その中に出てくるcollectionについて考えていきます。
前提として、postコントローラー、postモデルが存在し、
def index @posts = Post.all end
<%= post.title %> <%= post.body %>
とします。
collectionの使い方
まず、collectionをつかわずに、eachを使って繰り返しレンダリングさせると、
<% @posts.each do |post| %> <%= render 'post', post: post %> <% end %>
と表現できます。しかしこれでは毎回レンダリングをするため、負荷がかかってしまいます。 collectionを使うと、
<%= render partial: 'post', collection: @posts %>
と書くことで、内部で要素1つずつを取り出して処理をしてくれるため、何度もレンダリングをしません。負荷がかからないし、早い。また、部分テンプレートに渡る変数名は、partialで指定した値(post)になるので注意が必要。
collectionの省略記法
<%= render @posts %>
とかなり省略して書くことができるが、これが成立するためにはいくつかの決まりがある。
- 部分テンプレートが呼び出し元のテンプレートと同じディレクトリ内にある
- 部分テンプレートのファイル名がオプションで指定した変数の単数形である
- 部分テンプレート内で使用する変数名が、オプションで指定した変数の単数形である
今回でいうと、1は、呼び出し元のindex.html.erb
と部分テンプレートの_post.html.erb
が同じディレクトリ内
にあることが必要。2は、オプションで指定した変数名が@posts
なので、部分テンプレートは単数形の_post.html.erb
であることが必要。3は、オプションで@posts
を渡しているので、部分テンプレート内で使用する変数名は、post
であることが必要。
上記3つが守られていればかなり短いコードが書ける。
参考 https://b1840943.hatenablog.jp/entry/2018/05/24/221420 https://himakuro.com/rails-render-collection