- 投稿日:2019-03-10T22:33:21+09:00
http://localhost:3000/に特定のページを表示させたい(ルートへのルーティング設定)
専門的には、ルートへのルーティング設定をするというらしいです。
本当の初心者にとっては、そのワードすら知らないのでggrksと言われてもなかなか辛いところありますよね。。。ルートへのルーティング設定とは
Cloud9環境では、
https://〜.amazonaws.com/
Vagrant環境では、
http://localhost:3000/
にアクセスした時に、デフォルトで表示される「Welcome aboard」のページではなく、
自分で作ったページなり、アクションなりを表示させたい時にする設定のことです。ルートへのルーティング設定を行う
早速やっていきましょう!
コントローラーとアクションを作る
ターミナルに下記のコードをうちます。
$ rails g controller コントローラー名 アクション名
ルートファイルを編集する
「config/routes.rb」ファイルに下記のコードを書き込みます。
root :to => 'コントローラ名#アクション名'
例えば、
http://localhost:3000/
にアクセスした時に、
indexページを表示させたい場合は、
root :to => 'コントローラ名#index'
と書きます。これだけです。
もう少し理解が進んだら、ルートとは、ルーティング設定とは、というところも細かく書きたいです。
RESTfulなルーティングを設定するというところも書きたい。。
でも今は、これが精一杯なのでご勘弁ください。
- 投稿日:2019-03-10T21:55:13+09:00
府中産農産物直売所検索ページをとおしてかんたんなrailsアプリつくってみよう
概要
- 府中市が公開しているオープンデータを検索する事を事例にして、railsのアプリを作成する方法を丁寧に解説します。
作れるモノ
https://fuchu-nosanbutsu.herokuapp.com/
github
https://github.com/junara/fuchu-nosanbutsu
環境
- ruby (rbenv) 2.6.1
- rails 6.0.0 beta 2
- mac
使っているGem
手順
以下の手順で説明します
1. rails new ! (空のアプリを作ろう)
2. migration ! (テーブル作ろう)
3. import ! (データをインポートしよう)
4. view ! (データを表示しよう)
4. search ! (データを検索できるようにしよう)
5. deploy ! (herokuにアップしてみんなで使えるようにしよう)rails new ! (空のアプリを作ろう)
> bundle init Writing new Gemfile to /Users/junara/IdeaProjects/opendata/Gemfile > ls Gemfile Gemfile.lockrailsをインストールするために
gem "rails"
のコメントをアウトを外します。# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "rails"インストールします。フォルダの場所は
./vendor/bundle
にしますbundle install --path vendor/bundle # 省略ここでいちど起動を確認しましょう
rails s
http://localhost:3000
にアクセスします。下記の画面が出たら成功です。
migration ! (テーブル作ろう)
今回対象となるデータを見ます。 府中産農産物直売所マップ(平成30年11月現在) (CSV:11KB)
rails g model store ?[HEAD] Running via Spring preloader in process 84006 invoke active_record create db/migrate/20190310103813_create_stores.rb create app/models/store.rb invoke test_unit create test/models/store_test.rb create test/fixtures/stores.yml
db/migrate/20190310103813_create_stores.rbclass CreateStores < ActiveRecord::Migration[6.0] def change create_table :stores do |t| t.string :name t.string :description t.timestamps end end endrails db:migrate ?[HEAD] == 20190310103813 CreateStores: migrating ===================================== -- create_table(:stores) -> 0.0113s == 20190310103813 CreateStores: migrated (0.0113s) ============================import ! (データをインポートしよう)
下記のgemを入れます。importするときの定番。
gem 'activerecord-import'bundle install # 省略インポートするデータを府中市のHPからダウンロードして、下記に保存します。
府中産農産物直売所マップ(平成30年11月現在) (CSV:11KB)db/30chokubaijo_map.csv№,名 前,直売所住所,電話番号,営業時間,販売期間,休業日,販売品目,コメント # 省略取り込むためのメソッドをStoreモデルに書きます。
require 'csv' class Store < ApplicationRecord def self.import_csv(file) list = [] ActiveRecord::Base.transaction do CSV.foreach(file, encoding: 'cp932', headers: true) do |row| list << self.new(store_params(row)) end import list end end def self.store_params(row) { name: row['名 前'], description: row['販売品目'] } end end先ほど
db/30chokubaijo_map.csv
に保存したcsvをインポートします。rails c irb > Store.import_csv('db/30chokubaijo_map.csv') (0.2ms) SELECT sqlite_version(*) (0.1ms) begin transaction (0.1ms) SAVEPOINT active_record_1 # 省略 (0.1ms) RELEASE SAVEPOINT active_record_1 (0.8ms) commit transaction => #<struct ActiveRecord::Import::Result failed_instances=[], num_inserts=1, ids=[], results=[]>保存されているか確認します。
irb > Store.first.description Store Load (0.2ms) SELECT "stores".* FROM "stores" ORDER BY "stores"."id" ASC LIMIT ? [["LIMIT", 1]] => "トマト、きゅうり、おくら、いんげん、キャベツ、さつまいも、ブロッコリー、ねぎ、なす、モロヘイヤ、ピーマン、紫イモ、カリフラワー、じゃがいも、里いも、大根、ほうれん草、水菜 ほか" irb(main):009:0> Store.count (0.2ms) SELECT COUNT(*) FROM "stores" => 46view ! (データを表示しよう)
ルートを追加します。
config/routes.rbRails.application.routes.draw do root to: 'home#index' end上記で追加したhomeのアクションを行うコントローラーを新規で追加します。
app/controllers/home_controller.rbclass HomeController < ApplicationController def index @stores = Store.all end endapp/views/home/index.html.erb<h2> 府中産農産物直売所一覧 </h2> <% @stores.each do |store| %> <div> <h3> <%= store.name %> </h3> <div> <%= store.description %> </div> </div> <% end %>ここで確認します。
http://localhost:3000/search ! (データを検索できるようにしよう)
Activerecordでやるのは面倒なので、定番の検索のgem ransackを入れます。
gem 'ransack'で、インストール
bundle install
検索するために、indexアクションを修正します。
ransackの使い方は公式をどうぞ。app/controllers/home_controller.rbclass HomeController < ApplicationController def index @stores = Store.ransack(description_cont: params[:keyword]).result end end検索フォームをviewについかします。
<h2> 府中産農産物直売所一覧 </h2> <div> <%= form_with url: root_path, method: :get, local: true do |f| %> <%= f.text_field :keyword, value: params[:keyword], autocomplete: 'off' %> <%= f.submit '検索' %> <% end %> </div> <% @stores.each do |store| %> <div> <h3> <%= store.name %> </h3> <div> <%= store.description %> </div> </div> <% end %>ためします。
入力ボックスに乳酸菌飲料
と入力すると下記のようになれば成功です。deploy ! (herokuにアップして世界のみんなに使ってもらおう)
developmentとtest環境ではsqlite3, productionではpgをインストールします。
group :development, :test do gem 'sqlite3' end group :production do gem 'pg' endherokuへpushと同時に migrationが走るようにしましょう
release: bundle exec rake db:migrateherokuのアプリを作ります。
heroku create fuchu-nosanbutsu
現行のmasterをherokuへpushします。
git push heroku masterうまくdeployされたかみましょう
heroku openこういう表示なら成功です。
次にデータをインポートします。herokuでrails cをします。
heroku run rails c
既にやったようにインポートをします。
Store.import_csv('db/30chokubaijo_map.csv') Store.count # -> 46終わったらexit
exitherokuのページを再度リロードすると前述と同様に、一覧が表示され、検索も可能なことが確認できます。
完成です!!!これで、世界の人に府中市の農産物をアピールできました!
さらに発展させるには?
作ったのは、とてーもシンプルなアプリです。更に発展させるともっと使いやすいアプリになります。ご自身の興味にしたがって色々やってみましょう。
下記は、拡張例です!
是非挑戦しましょう!かんたんめ
- インポート対象を追加する:元のCSVには、住所などの列もあります。そちらもインポート対象にしましょう。
- インポートした列を表示に追加しましょう。
- 検索結果にページネーションを加えましょう
- 検索キーワード結果の文章にマッチしたキーワードをハイライトさせましょう。
- 複数のカラムを対象に検索できるようにしましょう
- bootstrapを導入して、装飾しましょう
- bulmaを導入して装飾しましょう
- 住所を押した時、google mapに遷移させましょう
- データを追加、編集できるフォームを追加しましょう
- herokuにdeployしましょう
そこそこ
- インポート時、重複列がある場合はupdateにしましょう
- 空白スペースで区切った場合はand検索になるようにしましょう
- 検索をページ遷移せずajaxで行いましょう
- 地図(google map)を表示させましょう
むずかしめ
- インクリメンタルサーチを入れましょう
- vue or reactでフロントを書きましょう
enjoy !
- 投稿日:2019-03-10T21:29:01+09:00
Rails: 5分で住所を自動入力しよう
もっと住所入力を楽にしてみない?
CtoCサービスのWebアプリを作る時、大抵のアプリには住所入力の項目があるかと思います。
その時に、自分で一から実装するのもいいけどめんどくさい時ってありますよね?
そんなあなたに5分で実装出来るプラグイン「gem」を教えたい。手順
まず最初に、下記で必要なjsファイルをダウンロードしてください。
ファイルは、assets/javascript/に置いてください。jquery.jpostal.js
1. 練習なので$rails g scaffold User
を事前に作っておきます。
2. 次にgem
を追加していきます。必須gem
gem 'jp_prefecture' gem 'jquery-rails'3. 次に
bundle install
をしましょ
4. ここでは、mifrationファイルを作っていきます。
$rails g migration AddColumnsToUsers postcode:integer
class AddColumnsToUsers < ActiveRecord::Migration[5.1] def change add_column :users, :postcode, :integer add_column :users, :prefecture_code, :integer add_column :users, :address_city, :string add_column :users, :address_street, :string add_column :users, :address_building, :string end end5.
$ rails db:migrate
をしましょ。
6. modelを編集していきます。
app/models/user.rbclass User < ApplicationRecord include JpPrefecture jp_prefecture :prefecture_code def prefecture_name JpPrefecture::Prefecture.find(code: prefecture_code).try(:name) end def prefecture_name=(prefecture_name) self.prefecture_code = JpPrefecture::Prefecture.find(name: prefecture_name).code end end7. Viewファイルを編集しています。
app/views/users/_form.html.erb<h2>Your address</h2> <p>zip code</p> <%= form.text_field :postcode %> <p>prefecture</p> <%= form.text_field :prefecture_code, collection: JpPrefecture::Prefecture.all, :value_method => :name, include_blank: '都道府県' %><br> <p>city</p> <%= form.text_field :address_city %> <p>street</p> <%= form.text_field :address_street %> <p>builbding name</p> <%= form.text_field :address_building %> <div class="actions"> <%= form.submit %>8. 次に、jQueryでjpostalメソッドの呼び出しをしていきます。
app/assets/javascripts/user.coffee$ -> $("#user_postcode").jpostal({ postcode : [ "#user_postcode" ], address : { "#user_prefecture_code" : "%3", "#user_address_city" : "%4", "#user_address_street" : "%5%6%7" } })こうすると、郵便番号を入力すると反映されるかと思います。
9. 最後に、Controllerでストロングパラメーターを設定します。
app/controllers/users_controller.rbdef zipedit params.require(:user).permit(:postcode, :prefecture_name, :address_city, :address_street, :address_building) endすでに、関連する記事がいくつかありますが更新日が古かったので個人的メモのついでにアップデートしてみました。
こんな感じで、誰かの助けになればと思います。なお、最短でやって5分なので思いのほか時間がかかっても責めないでないください。
- 投稿日:2019-03-10T21:29:01+09:00
Rails: 5分で住所を自動入力かしよう
もっと住所入力を楽にしてみない?
CtoCサービスのWebアプリを作る時、大抵のアプリには住所入力の項目があるかと思います。
その時に、自分で一から実装するのもいいけどめんどくさい時ってありますよね?
そんなあなたに5分で実装出来るプラグイン「gem」を教えたい。手順
まず最初に、下記で必要なjsファイルをダウンロードしてください。
ファイルは、assets/javascript/に置いてください。jquery.jpostal.js
1. 練習なので$rails g scaffold User
を事前に作っておきます。
2. 次にgem
を追加していきます。必須gem
gem 'jp_prefecture' gem 'jquery-rails'3. 次に
bundle install
をしましょ
4. ここでは、mifrationファイルを作っていきます。
$rails g migration AddColumnsToUsers postcode:integer
class AddColumnsToUsers < ActiveRecord::Migration[5.1] def change add_column :users, :postcode, :integer add_column :users, :prefecture_code, :integer add_column :users, :address_city, :string add_column :users, :address_street, :string add_column :users, :address_building, :string end end5.
$ rails db:migrate
をしましょ。
6. modelを編集していきます。
app/models/user.rbclass User < ApplicationRecord include JpPrefecture jp_prefecture :prefecture_code def prefecture_name JpPrefecture::Prefecture.find(code: prefecture_code).try(:name) end def prefecture_name=(prefecture_name) self.prefecture_code = JpPrefecture::Prefecture.find(name: prefecture_name).code end end7. Viewファイルを編集しています。
app/views/users/_form.html.erb<h2>Your address</h2> <p>zip code</p> <%= form.text_field :postcode %> <p>prefecture</p> <%= form.text_field :prefecture_code, collection: JpPrefecture::Prefecture.all, :value_method => :name, include_blank: '都道府県' %><br> <p>city</p> <%= form.text_field :address_city %> <p>street</p> <%= form.text_field :address_street %> <p>builbding name</p> <%= form.text_field :address_building %> <div class="actions"> <%= form.submit %>8. 次に、jQueryでjpostalメソッドの呼び出しをしていきます。
app/assets/javascripts/user.coffee$ -> $("#user_postcode").jpostal({ postcode : [ "#user_postcode" ], address : { "#user_prefecture_code" : "%3", "#user_address_city" : "%4", "#user_address_street" : "%5%6%7" } })こうすると、郵便番号を入力すると反映されるかと思います。
9. 最後に、Controllerでストロングパラメーターを設定します。
app/controllers/users_controller.rbdef zipedit params.require(:user).permit(:postcode, :prefecture_name, :address_city, :address_street, :address_building) endすでに、関連する記事がいくつかありますが更新日が古かったので個人的メモのついでにアップデートしてみました。
こんな感じで、誰かの助けになればと思います。なお、最短でやって5分なので思いのほか時間がかかっても責めないでないください。
- 投稿日:2019-03-10T19:47:12+09:00
プログラミング学習記録22〜ToDoアプリ完成(写経)〜
今日やったこと
- Udemyの「Web開発入門完全攻略コース - プログラミングをはじめて学び創れる人へ!未経験から現場で使える開発スキルを習得!」のセクション15の215~248
なんとかコースを1周しました。
以下、パートごとの学習メモです。
セクション15Ruby on Rails 5入門
215.イントロダクション -Ruby on Rails 5入門-
このセクションの概要。
216.開発環境構築
AWS Cloud9
Ruby on Rails 5.1.4
Ruby 2.5.0
sqlite3なぜか5.1.4をインストールしても,5.1.6.1になってしまうのですが、大きな違いはないと思うので、このまま進みます。
ターミナルでrailsをインストールしました。
217.railsプロジェクトの作成
helloプロジェクトを作成しました。
218.ディレクトリ構成について
MVC(モデル・ビュー・コントローラー)
Model→データ
View→画面
Controller→ModelとViewをつなぐ処理どのファイルをいじっていくのかについての説明を受けました。
219.はじめてのRuby on Railsプログラミング
erbはテンプレートエンジンと呼ばれ、HTMLの中にrubyを組み込むことができます。
controllers、index.html.erb、routes.rbをいじり、無事Hello World!を表示させることができました。
220.TODOアプリの完成形の確認
この講座で作るTODOアプリの完成形を確認しました。
221.プロジェクトの作成
これから作るTODOアプリのプロジェクトを作りました。
動画の通りやっていたはずなのにうまくいかないハプニングが起こり、セクションの初めに戻るも解決せず…
※後日追記
todoのgemfileの方もgem 'sqlite3','~> 1.3.6’にして、ターミナルでbundle updateをしたらうまくいきました。222.コントローラーの作成
tasks_controllerを作りました。
223.モデルの作成
224.マイグレーションファイルの編集
225.DBスキーマをDBに反映する
226.初期データ作成
227.ルーティングの設定
228.一覧画面のcontrollerを開発
229.一覧画面のviewを開発
230.一覧画面の動作確認
231.一覧画面へ新規追加画面へのリンクを追加
232.新規追加画面のviewを開発
233.新規追加画面のcontrollerを開発
234.新規追加画面の動作確認
235.バリデートの追加
テキストボックスに何も入力されていないときは、データベースに保存しないようにする設定をしました。
236.一覧画面から編集画面へのリンクを追加
237.編集機能のviewを開発
238.編集画面のcontrollerを開発
239.編集画面の動作確認
240.削除機能のviewを開発
241.削除機能のcontrollerを開発
242.削除機能 動作確認
243.チェックボックスのトグル動作について
244.jQueryのインストール
245.ルーティング設定
246.チェックボックスのトグル動作のcontrollerを開発
247.チェックボックスのトグル動作のクライアント側を開発
248.トグル動作の動作確認
セクション15Ruby on Rails 5入門
途中トラブルがありつつも、なんとか終えることができました。
よくわからずただ写経している部分がほとんどなのですが、それでも一通り体験できてよかったと思います。
今後はこの講座の復習を進めながら、中村先生のrailsのコースを受けてみます。
まだまだわからないことだらけですが、とりあえずコースを1周して達成感をしています。raisはProgateすらやっていない状態で講座を受けたこともあり、理解が苦しかったです。
なので、これからProgateのrailsをやってみたいと思います。
ということで、明日からも引き続きプログラミング学習頑張ります。
おわり
- 投稿日:2019-03-10T18:23:20+09:00
Railsのrmagick(画像リサイズ用のgem)インストールエラー
- 投稿日:2019-03-10T18:02:19+09:00
①連続した数を配列に入れる。②文字列からn個抜き出すと何通りあるか?
①1〜5の連続した数を配列に入れる
m = (1..5) => 1..5 m = (1..5).to_a => [1,2,3,4,5]to_aを使うと配列に変換される。
②文字列から何個抜き出すと何通りあるか?
文字列.combination
[1,2,3,4]の中からn個抜き取る。重複しない組み合わせ。逆順含まない(例[1,2][2,1]は含まない)n = 2 [1,2,3,4].combination(n).to_a => [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]文字列.permutation
[1,2,3,4]の中からn個抜き取る。重複しない組み合わせ。逆順含む(例[1,2][2,1]含む)n = 2 [1,2,3,4].permutation(n).to_a => [[1, 2], [1, 3], [1, 4], [2, 1], [2, 3], [2, 4], [3, 1], [3, 2], [3, 4], [4, 1], [4, 2], [4, 3]]
- 投稿日:2019-03-10T17:40:43+09:00
fields_forにハマった
日記に画像を登録するのに、diaryモデルとimageモデルを使用して実装。
画像の登録はcarrierwaveを使いました。
別モデルのデータを表示するにはアソシエーションとfields_forでのフォーム生成が必要。
アソシエーション
diary:image = 1:多 の関係性なので
diary.rbhas_many :images, dependent: :destroy #オプション(dependent: :destroy)で日記が消えたらそれに関連する画像も消える設定にした。image.rbbelongs_to :diaryリファレンスキー追加
ターミナルrails g migration add_references_to_images diary:referencescreate_images.rbclass CreateImages < ActiveRecord::Migration[5.2] def change create_table :images do |t| t.string :name t.references :diary, foreign_key: true #追記 t.timestamps end end endadd_references_to_images.rbclass AddReferencesToImages < ActiveRecord::Migration[5.2] def change add_reference :images, :diary, foreign_key: true end endこれでimagesテーブルにdiary_idが入る。
gemインストール
Gemfilegem 'carrierwave'ターミナルbundle installuploader追加
ターミナルrails g uploader imageimage.rbmount_uploader :name, ImageUploader #nameカラムに画像のデータが入ります。入力フォーム作成
_form.html.erb(diary)<%= form_for(@diary) do |form| %> <% if @diary.errors.any? %> <div id="error_explanation"> <%= pluralize(angel.errors.count, "error") %> prohibited this diary from being saved: <div class="field"> <%= form.label :date %> <%= form.date_field :date, value: Time.now.strftime("%Y-%m-%d") %> </div> <div class="field"> <%= form.label :content %> <%= form.text_area :content %> </div> #異なるモデル(imageモデル)をいじるときはform.fields_forを使う <%= form.fields_for :images do |image| %> <div class="field"> <%= image.label :image %> #表示名 <%= image.file_field :name %> #ファイル選択ボックスを生成し、データの送り場所を指定 <%= image.hidden_field :id %> </div> <% end %> <div class="actions"> <%= form.submit %> </div> <% end %> <%= link_to 'Back', diaries_path %>accepts_nested_attributes_for
diaries_controller.rbclass DiariesController < ApplicationController def new @diary = current_user.diaries.new @diary.images.build end def create @diary = current_user.diaries.build(diary_params) if @diary.save redirect_to @diary, notice: 'diary was successfully created.' else render :new end end private def diary_params params.require(:diary).permit(:date ,:gift ,:content ,:user_id ,:angel_id, images_attributes: [:id, :name, :_destroy])#編集や削除の際にid,;_destroyが必要らしい end enddiary.rbaccepts_nested_attributes_for :imagesモデルでaccepts_nested_attributes_forを指定することでコントローラのstrongparameter内でimages_attributeを使ってカラムを指定することができる
画像の表示
show.html.erb<%= image_tag @diary.images.first.name.to_s %>
- 投稿日:2019-03-10T16:29:45+09:00
Factory_Botで undefined method '×××' in '○○○' factoryが発生する場合
RailsでFactory Botを使う時にタイトルのエラーが発生したので、原因と対応のメモです。
バージョン
Ruby 2.5.1
Rails 5.2.2
Factory Bot 5.0.1エラーメッセージ
具体的には以下のエラーメッセージが出力されました。
/vendor/bundle/ruby/2.5.0/gems/factory_bot-5.0.1/lib/factory_bot /definition_proxy.rb:97:in `method_missing': undefined method 'name' in 'user' factory (NoMethodError)解決方法
エラー発生時のファクトリ
spec/factories/user.rbFactoryBot.define do factory :user do name "Beer Lover" email "beerlover@example.com" password "beerlover" end end↓修正版
spec/factories/user.rbFactoryBot.define do factory :user do name {"Beer Lover"} email {"beerlover@example.com"} password {"beerlover"} end end属性名に設定する値は{}で囲う必要があります。
Factory Botのバージョンが5.0.0からは{}で囲わないとエラーがでるように変更されたみたいですね。
- 投稿日:2019-03-10T11:31:58+09:00
[Rails]パーシャルをパーシャル名のみで呼び出そうとしてハマったところ
Railsチュートリアルの演習で、パーシャル名によるパーシャルの呼び出しでハマったポイントをまとめます。
環境
・Rails 5.1.6
・Rails チュートリアル第4版(Rails5.1)演習問題
演習13.3.2.1
Homeページをリファクタリングして、if-else文の分岐のそれぞれに対してパーシャルを作ってみましょう。
演習前時点でのHomeビューは以下の通り。
/sample_app/app/views/static_pages/home.html.erb<% if logged_in? %> <div class="row"> <aside class="col-md-4"> <section class="user_info"> <%= render 'shared/user_info' %> </section> <section class="micropost_form"> <%= render 'shared/micropost_form' %> </section> </aside> </div> <% else %> <div class="center jumbotron"> <h1>Welcome to the Sample App</h1> <h2> This is the home page for the <a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a> sample application. </h2> <%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %> </div> <%= link_to image_tag("rails.png", alt: "Rails logo"), 'http://rubyonrails.org/' %> <% end %>上記の
if
とelse
の中身をそれぞれパーシャルに切り出し、render
で呼び出すことによって、if
とelse
の中身を一行でスッキリ書こうという問題ですね。自分の解答
/sample_app/app/views/static_pages/
内に二つのパーシャルlogged_in
とnot_logged_in
を切り出し、home.html.erb
から呼び出す。/sample_app/app/views/static_pages/home.html.erb<% if logged_in? %> <%= render 'logged_in' %> <% else %> <%= render 'not_logged_in' %> <% end %>パーシャルを
home.html.erb
と同じフォルダに配置したため、パーシャル名のみで指定できると考え、上のように記述しました。このときのフォルダ構成は以下の通り。views/ └ static_pages/ ├ _logged_in.html.erb ├ _not_logged_in.html.erb └ home.html.erb一見これで問題なく動作していたのですが、homeから空白のマイクロポストを投稿した際に下記のようなエラーが発生しました。
ActionView::Template::Error (Missing partial microposts/_logged_in
views/microposts/
内に_logged_in
パーシャルが無いと怒られています。
views/static_pages/
内の_logged_in
パーシャルを探して欲しいのですが...原因
コントローラからrenderでビューを描画したとき、パーシャル名のみで指定できるパーシャルは、コントローラと対応するビューフォルダ(views/コントローラ名)内のパーシャルである。
今回の場合、homeから投稿したmicropostが不正(空白または141文字以上)のとき、エラーメッセージを付け加えてhomeビューを再描画します。
/sample_app/app/controllers/microposts_controller.rbclass MicropostsController < ApplicationController before_action :logged_in_user, only: [:create, :destroy] def create @micropost = current_user.microposts.build(micropost_params) if @micropost.save flash[:success] = "Micropost created!" redirect_to root_url else render 'static_pages/home' # micropostが不正な場合、homeを再描画 end end def destroy end private def micropost_params params.require(:micropost).permit(:content) end endこのように、マイクロポストの作成に失敗したときは、
microposts_controller.rb
から、render 'static_pages/home'
によって、homeビューを再描画しています。このとき、パーシャル名のみで指定できるパーシャルはviews/microposts
内のパーシャルです。そのため、パーシャル名のみでパーシャルを指定すると、views/microposts
内を探してしまい、エラーとなります。views/ ├ microposts/ ⬅️ ここを探してしまう! └ static_pages/ ├ _logged_in.html.erb ├ _not_logged_in.html.erb └ home.html.erb逆に、マイクロポストの作成に成功した場合や、直接homeのページのURLを入力した場合などは、
static_pages_controller.rb
からhomeビューを描画するので、views/static_pages
内のパーシャルを探します。そのため、この場合はパーシャル名のみでパーシャルを呼び出していても、エラーが起きていませんでした。正しい解答
/sample_app/app/views/static_pages/home.html.erb<% if logged_in? %> <%= render 'static_pages/logged_in' %> <% else %> <%= render 'static_pages/not_logged_in' %> <% end %>
views/
からの相対パスを指定すると、期待通りのパーシャル(logged_in
)を呼び出すことができ、エラーが出なくなりました。まとめ
ビューから、パーシャル名のみでパーシャルを呼び出すときは、そのビューを描画するコントローラを考慮する必要がある。
- 投稿日:2019-03-10T02:56:08+09:00
binding.pryでデバッグする
binding.pryを使うためにGemをインストール。
Gemfilegroup :development do gem 'pry-rails' gem 'pry' endbundle installを実行する。
$ bundle installコンソールを立ち上げる。
$ rails cデバックしたいブレークポイントにbinding.pryと書く。
viewの場合は、<% binding.pry %>サーバーを起動し、ブレイクポイントを設定したアクションに遷移するとコンソールがとまる。
binding.pryから抜けるコマンド
[1] pry(Hoge)> exitbinding.pryから強制的に抜けるコマンド
プロセスを終了してしまうため、rails sが落ちる。[2] pry(Hoge)> exit![3] pry(Hoge)> !!!