- 投稿日:2020-07-31T23:09:14+09:00
ActiveHashについて
DB設計をしてる時に便利なgemを見つけたのでまとめてみたいと思います。
ActiveHashとは
都道府県一覧やカテゴリーなど「基本的に変更されないデータ」(区分情報等)があったとします。基本的に変更されないデータであるため、データベースに保存する必要性がありません。
ですがビューファイルなどに都道府県のオプションを書くと見るに耐えないコードになってしまいます。
そういう悩みを解決するのに便利なのがactive_hash。
ハッシュデータをモデルとして定義することで、ActiveRecordと同じように使えることができます。それでは定義の仕方を見ていきましょう。
まずGemfileにactive_hashを記載して、bundle installします。
gem 'active_hash'モデル作成
今回はArticleモデルとgenreモデルを作りたいと思います。
rails g model articlerails g model genre --skip-migrationgenreモデルには情報をデータベースに持たせないのでマイグレーションファイルを作成する必要はありません。
ハッシュの作成
次にデータをハッシュの形で定義します。
app/models/genre.rbclass Genre < ActiveHash::Base self.data = [ { id: 1, name: '--' }, { id: 2, name: '経済' }, { id: 3, name: '政治' }, { id: 4, name: '地域' }, { id: 5, name: '国際' }, { id: 6, name: 'IT' }, { id: 7, name: 'エンタメ' }, { id: 8, name: 'スポーツ' }, { id: 9, name: 'グルメ' }, { id: 10, name: 'その他' } ] endここで気をつけるのはActiveHash::BaseをGenreモデルに継承することで
ActiveRecordのメソッド(allなど)が使えるようになります。使用するクラスにアソシエーションを定義する。
ActiveHash::Associations::ActiveRecordExtensionsモジュールをArticleクラスにextendする事で
このモジュールに定義してあるbelongs_to_active_hashメソッドをArticleのクラスメソッドとして
使用する事が出来ています。app/models/article.rbclass Article < ApplicationRecord extend ActiveHash::Associations::ActiveRecordExtensions belongs_to_active_hash :genre end endコンソールで試してみましょう
irb(main):001:0> Article.create(genre_id:1) => #<Article id: nil, title: nil, genre_id: 1, created_at: nil, updated_at: nil>無事Articleモデルでgenreモデルで定義したデータを取得することができました。
- 投稿日:2020-07-31T21:55:20+09:00
Railsのリクエストがルーティングにアクセスするまでの流れについて
概要
Railsアプリケーションでのリクエストからルーティングにアクセスするまでをまとめてみました。
Railsのルーティングとは
役割
『クライアントからのリクエストを判断し、どのプログラムに処理を渡すのか』を決める役割を担っている部分になります。
処理に必要な情報
『リクエストURI』 と 『HTTPメソッド』 です。
つまり...
この2つの情報を持ったリクエストがクライアントから送信されていることになります。
今回のゴール
リクエストは
・ 『どうやってRailsアプリにアクセスしているのか?』
・ 『アクセス時にどのような情報を持っているのか?』
について、知ることです。
<1> どうやってRailsアプリにアクセスしているのか?
結論
クライアントはRailsアプリのあるWebサーバの所在を表す URI をもとにアクセスしている。
URIとは
一般的にURLという意味で使われている
例)http://sample.com/samples
といったものです。このURIを分解してすると、このように分けられる
・
http:
=> スキーム・
sample.com
=> ホスト・
samples
=> パススキームとは・・・
『どんな手段で通信するのか』を明示的に示している部分になります。
つまり今回の場合だと『 HTTP通信をしますよ 』ということを示しています。HTTPとは・・・
Hyper Text Transfer Protocolの略で、
Webページを構成するHTMLなどのコンテンツの送受信に用いられる通信プロトコルです。また、SSL/TLSプロトコル(暗号化と認証の機能がある)を用いて行われるHTTP通信を行うことをHTTPS通信(https:)と呼び、HTTP通信よりも安全です。
通信プロトコルとは・・・
『ネットワーク上でデータ通信するためのルールをまとめたもの』です。
よく例えで使われているのが、言語やマナーでした。
つまり、人間の世界でも「郷に入れば郷に従え」ということわざがあるように
コンピュータの世界にもデータをスムーズにやりとりするために細かい取り決めがあり
それを通信プロトコルと呼びます。また、通信プロトコルはOSI参照モデルをもとに7つの階層に分けることによって
それぞれの階層で行われる通信機能を定義しています。ちなみに、HTTPは第7階層のアプリケーション層に区分されています。
ホストとは・・・
『どこのサーバにアクセスするのか』を明示的に示している部分になります。
今回の場合だと、DNSというサービスを使って
『sample.com
のサーバにアクセスしますよ 』ということを示しています。DNSとは・・・
Domain Name Systemの略で人間が覚えにくいIPアドレスにドメイン名を割り当て、覚えやすい情報にするシステムです。
例) 127.0.12.1(IPアドレス) <=> sample.com(ドメイン名)
パスとは・・・
『どのファイルをの情報が欲しいのか』を明示的に示している部分になります。
今回の場合だと『samples
ファイルを下さいね 』ということを示してします。<1> まとめ
・WebブラウザがWebサーバと通信する時は、HTTP通信を使用する。
・クライアントはURIをもとにアクセスしている。
・URIは3つの部分に分けられる。(スキーム・ホスト・パス)<2> アクセス時にどのような情報を持っているのか
結論
HTTPリクエストというクライアントからの情報です。
HTTPリクエストとは・・・
HTTP通信をする際にWebブラウザからWebサーバへ送信される『リクエストライン』・『ヘッダー』・『ボディ』の3つで構成されるリクエストになります。
HTTPリクエストのイメージGET /samples HTTP/1.1 // リクエストライン Host: sample.com /* ヘッダー Accept-Language: ja */ // 空白行 q=test&test=%E6%A4%9C // ボディまた、反対にWebサーバからWebブラウザ送信される通信を『HTTPレスポンス』といい
『HTTPリクエスト』と『HTTPレスポンス』をワンセットでやりとりすることで
Webアプリケーションが出来ています。リクエストラインとは・・・
Webサーバ内のどのリソースにどんな操作をするかを表した部分で
『HTTPメソッド』・『リクエストURI』・『HTTPバージョン』の3つの要素を1行で表したものです。<HTTPメソッド> <リクエストURI> <HTTPバージョン> GET /samples HTTP/1.1HTTPメソッドとは・・・
Webサーバに対して『やって欲しい操作』を明示的に示している部分になります。
種類は8つありますが、基本的にRailsで使われるのは4種類になります。
メソッド 操作の内容 GET 指定されたURIのリソースを取得する。少量のデータを送信する。 POST 大量のデータや機密性のあるデータを送信する。 PUT/PATCH 指定したURIにリソースを保存する。 DELETE 指定したURIのリソースを削除する。 リクエストURIとは・・・
リクエストの対象となるデータを指す情報のことです。
HTTPバージョンとは・・・
Webブラウザがサポートするバージョンのことです。
今回の例だとバージョンが『1.1』という意味になります。ヘッダーとは・・・
リクエストの詳細情報を表した部分になります。
唯一の必須のヘッダーは『Host』で、ホスト名を指定して『どのWebサーバへのリクエストか』を明示的に示します。また、ヘッダーの種類はたくさんあり、Webブラウザ側でサポートするデータのタイプ、データの圧縮方法、ブラウザの種類などの情報があります。
ヘッダーイメージHost: sample.com // リクエスト先のサーバ User-Agent: // サポートするブラウザの種類 Accept: // ブラウザが受信可能なデータ形式 Accept-Encoding: // ブラウザのデータの圧縮方法 Accept-Language: // ブラウザが受信可能な言語 ...ボディとは
Webサーバにデータを送る時に使用する部分になります。
HTTPメソッドがPOSTとPUTの時に使用され、ヘッダーの下に空白行を一行入れ、その下に記述されます。
また、使用されない場合は省略されます。<2> まとめ
・Webサーバーは、クライアントからの情報をHTTPリクエストで受信する。
・HTTPリクエストは3つの部分に分けられる。(リクエストライン・ヘッダー・ボディ)
・Railsのルーティングに必要な情報は、リクエストラインの中に入っている。以上になります。
- 投稿日:2020-07-31T20:50:33+09:00
Railsでkaminariを使う
プログラミングの勉強日記
2020年7月31日 Progate Lv.226
概要
こちらの記事で扱ったgemのkaminariを説明する。kaminariは1つのページに掲載するコンテンツが増えたときに複数ページに分けて表示させるページネーションを簡単に実装することができる。
ページネーションを使うことで、情報量の多いサイトをまとめられるということだけではなく、表示される項目が一定数を超えると自動的に次のページへ内容を移行することもできるので便利である。使い方
kaminariを使うためにGemfileを編集する。
Gemfilegem 'kaminari'Gemfileを編集したら、kaminariをインストールする。
ターミナルbundle installこれでkaminariで定義されたメソッドや機能を使うことができるようになる。
ページネーションの定義
コントローラとビューでページネーションが表示されるようにする。
controllerファイルdef index @users = User.page(params[:page]).per(10) endビューファイル<%# ページネーションの表示 %> <%= paginate @users %>見た目の変更
kaminariで表示されるページネーションはビューの中でCSSを適用させることはできない。なので、見た目を変えたい場合は
app/view/kaminari
フォルダを作り、その中にページネーションの部分のHTMLが記述されているようにターミナルで以下のコマンドを実行する。ターミナル$ rails g kaminari:views defaultBootstapに合わせる
bootstrap用にカスタマイズすることもできる。このためにはもう一度Gemfileを変更する。
Gemfilegem 'kaminari-bootstrap', '~> 3.0.1'Gemfileを編集したら、インストールする。
ターミナルbundle installそして、
config/config/locales/kaminari_ja.yml
を追加して編集する。config/locales/kaminari_ja.ymlja: views: pagination: first: "« 最初" last: "最後 »" previous: "‹ 前" next: "次 ›" truncate: "..."
- 投稿日:2020-07-31T19:55:10+09:00
Railsアプリで日時の取得にはどのクラスを使うべきか(Time, DateTime, TimeWithZone)
日時の取得はどのクラスを使うべきか
- Timeクラス
- DateTimeクラス
- TimeWithZoneクラス
Railsでは、特別な理由がない限り、
TimeクラスやDateTimeクラスより、TimeWithZoneクラスで統一した方が良い。タイムゾーンについて
タイムゾーンを設定する場所は3箇所あります。
- システム
- 環境変数
ENV['TZ']
- application.rb
application.rbにどのタイムゾーンが設定してあるか確認するには、
Time.zone.name
を使います。# application.rb config.time_zone = 'Tokyo' Time.zone.name => "Tokyo"どのタイムゾーンが使われるのか
ややこしいことに、クラスやそのクラスに関連するメソッドによってどのタイムゾーンが使われるか変わります。
例えば、
Timeクラスに関連するメソッドnow
を使ったTime.now
は環境変数のタイムゾーンを使い、
Timeクラスに関連するメソッドcurrent
を使ったTime.current
はapplication.rbのタイムゾーンを使います。#環境変数が使われ、classはTimeになる [1] pry(main)> Time.now => 2020-07-31 19:39:18 +0900 [2] pry(main)> Time.now.class => Time #application.rbが使われ、classはTimeWithZoneになる [3] pry(main)> Time.current => Fri, 31 Jul 2020 19:39:35 JST +09:00 [4] pry(main)> Time.current.class => ActiveSupport::TimeWithZone現在の日時の取得にはTime.currentかTime.zone.nowを使おう
現在の日時を取得する場合、以下の方法があります。
- Time.now (環境変数のタイムゾーンを使う)
- DateTime.now (環境変数のタイムゾーンを使う)
- Time.current (application.rbのタイムゾーンを使う)
- Time.zone.now (application.rbのタイムゾーンを使う)
結論としては、TimeWithZoneクラスである3または4を使っておいた方が良いです(もし国際的なアプリケーションにしようと思ったら色々と器用に扱える為)。
# 環境変数のタイムゾーンが使われる [1] pry(main)> Time.now => 2020-07-31 19:43:14 +0900 #Timeクラス [2] pry(main)> DateTime.now => Fri, 31 Jul 2020 19:43:21 +0900 #DateTimeクラス # application.rbのタイムゾーンが使われる [3] pry(main)> Time.current => Fri, 31 Jul 2020 19:43:26 JST +09:00 #ActiveSupport::TimeWithZoneクラス [4] pry(main)> Time.zone.now => Fri, 31 Jul 2020 19:43:32 JST +09:00 #ActiveSupport::TimeWithZoneクラス参考記事
以下の記事を参考にしました。記事ではとても詳しく説明してあります。
https://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c
- 投稿日:2020-07-31T18:08:51+09:00
木構造のacts_as_treeで、N+1を消し去る
木構造
古いコードを見ると、アンチパターンが多いですね。今回も同様にアンチパターンの一つである隣接リストが使われていました。さらに、N+1問題が放置され、パフォーマンス的に悪いということで対応することになりました。
今回は、たった2階層だったので、隣接リストでもあまり問題がなさそうです。GitHub
https://github.com/amerine/acts_as_tree
使い方
https://github.com/amerine/acts_as_tree#example 引用
class Category < ActiveRecord::Base acts_as_tree order: "name" end root = Category.create("name" => "root") child1 = root.children.create("name" => "child1") subchild1 = child1.children.create("name" => "subchild1") root.parent # => nil child1.parent # => root root.children # => [child1] root.children.first.children.first # => subchild1前提
parent_id
(あるいは、任意のキー) を木構造の親キーとします。schema例
create_table "technologies", force: :cascade do |t| t.string "name" t.bigint "parent_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["parent_id"], name: "index_technologies_on_parent_id" endN+1の消し去り方
modelに追加した
acts_at_tree
によって、children
メソッドが生えますので、そちらをincludesして関連付け、事前に最小限のクエリ回数にて読み込まれるようにします。解消コード
# model class Technology < ApplicationRecord acts_as_tree def dig if children.empty? self else children.map(&:dig) end end endincludesを付与してあげます。
# console Technology .where(parent: nil) .includes(children: { children: [:children] })) .map(&:dig)
- 投稿日:2020-07-31T18:08:51+09:00
Ruby on Railsの木構造Gemのacts_as_treeで、N+1を消し去る
手元動作環境
当然、サービスインしているコードを乗せるわけにはいかないので、手元環境で似たようなコードを書いて動作検証しています。
- ruby 2.7.1p83
- Rails 6.0.3.2
- acts_as_tree (2.9.1)
木構造
古いコードを見ると、アンチパターンが多いですね。今回も同様にアンチパターンの一つである隣接リストが使われていました。さらに、N+1問題が放置され、パフォーマンス的に悪いということで対応することになりました。
今回は、たった2階層だったので、隣接リストでもあまり問題がなさそうです。GitHub
https://github.com/amerine/acts_as_tree
使い方
https://github.com/amerine/acts_as_tree#example 引用
class Category < ActiveRecord::Base acts_as_tree order: "name" end root = Category.create("name" => "root") child1 = root.children.create("name" => "child1") subchild1 = child1.children.create("name" => "subchild1") root.parent # => nil child1.parent # => root root.children # => [child1] root.children.first.children.first # => subchild1前提
parent_id
(あるいは、任意のキー) を木構造の親キーとします。schema例
create_table "technologies", force: :cascade do |t| t.string "name" t.bigint "parent_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.index ["parent_id"], name: "index_technologies_on_parent_id" endN+1の消し去り方
modelに追加した
acts_at_tree
によって、children
メソッドが生えますので、そちらをincludesして関連付け、事前に最小限のクエリ回数にて読み込まれるようにします。解消コード
# model class Technology < ApplicationRecord acts_as_tree def dig if children.empty? self else children.map(&:dig) end end endincludesを付与してあげます。
# console Technology .where(parent: nil) .includes(children: { children: [:children] })) .map(&:dig)response
2階層のコードを抜き出して見ると、このような形になります。
{ "id":6, "name":"AWS", "parent_id":null, "children":[ { "id":7, "name":"コンピューティング", "parent_id":6, "children":[ { "id":8, "name":"EC2", "parent_id":7 }, { "id":9, "name":"Elastic Beanstalk", "parent_id":7 }, { "id":10, "name":"Lambda", "parent_id":7 } ] } ] }発行SQLの比較
includesがない場合の例
60件ぐらいデータを入れてみた
データに応じて、SQLの数が増加していくSELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IS NULL SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 1], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 2], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 3], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 4], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 5], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 6], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 6]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 7], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 7]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 8], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 9], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 10], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 11], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 11]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 12], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id SELECT 1 AS one F_i SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id SE= $1 [["parent_id", 14]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 15], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 16], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 16]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 17], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "ent_id", 19], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 20], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 20]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 21], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 22], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 23], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" W" = $1 [["parent_id", 24]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 25], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 26], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 27], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 28], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 29], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIM SELECT 1 AS one FROM "technologies" WIMIT $2 [["parent_id", 31], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 31]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 32], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 33], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 34], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 34]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 35], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 36], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 37], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 38], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 39], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 39]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 40], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 41], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 42], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 42]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 43], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 44], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 44]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 45], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 46], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 46]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 47], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 48], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 49], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "ent_id", 51], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 51]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 52], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 53], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 54], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 55], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" SELECT "technologies".* FROM "technolent_id", 56], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 57], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 58], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 59], ["LIMIT", 1]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" = $1 [["parent_id", 59]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["paren SELECT 1 AS one FROM "ent_id", 61], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 62], ["LIMIT", 1]] SELECT 1 AS one FROM "technologies" WHERE "technologies"."parent_id" = $1 LIMIT $2 [["parent_id", 63], ["LIMIT", 1]]N+1問題解消時の例
SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IS NULL SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IN ($1, $2, $3, $4, $5, $6) [["parent_id", 1], ["parent_id", 6], ["parent_id", 46], ["parent_id", 51], ["parent_id", 55], ["parent_id", 59]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29) [["parent_id", 2], ["parent_id", 3], ["parent_id", 4], ["parent_id", 5], ["parent_id", 7], ["parent_id", 11], ["parent_id", 14], ["parent_id", 16], ["parent_id", 20], ["parent_id", 24], ["parent_id", 31], ["parent_id", 34], ["parent_id", 39], ["parent_id", 42], ["parent_id", 44], ["parent_id", 47], ["parent_id", 48], ["parent_id", 49], ["parent_id", 50], ["parent_id", 52], ["parent_id", 53], ["parent_id", 54], ["parent_id", 56], ["parent_id", 57], ["parent_id", 58], ["parent_id", 60], ["parent_id", 61], ["parent_id", 62], ["parent_id", 63]] SELECT "technologies".* FROM "technologies" WHERE "technologies"."parent_id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28) [["parent_id", 8], ["parent_id", 9], ["parent_id", 10], ["parent_id", 12], ["parent_id", 13], ["parent_id", 15], ["parent_id", 17], ["parent_id", 18], ["parent_id", 19], ["parent_id", 21], ["parent_id", 22], ["parent_id", 23], ["parent_id", 25], ["parent_id", 26], ["parent_id", 27], ["parent_id", 28], ["parent_id", 29], ["parent_id", 30], ["parent_id", 32], ["parent_id", 33], ["parent_id", 35], ["parent_id", 36], ["parent_id", 37], ["parent_id", 38], ["parent_id", 40], ["parent_id", 41], ["parent_id", 43], ["parent_id", 45]]
- 投稿日:2020-07-31T17:43:07+09:00
Controllerに定義するアクション一覧
- 投稿日:2020-07-31T16:00:25+09:00
hamlのヘルパーメソッドの使用例
link_toの使い方
link_toを使用する際、
link_to "テキスト","リンク先のパス"などで使われることが多いが、テキスト等であればそこに表示したいテキストを記入すればよいが、ロゴを指定しないととなると少し書き方が変わってくる。
例えば
VScodeのimageの中に"logo.png"というロゴを入れてそれを指定する場合は= link_to root_path do = image_tag src ="logo.png",size"140x40"と記入してあげるとlogoを表示することができる。
submitでのロゴの使い方
form_forなどでlogoボタンを使用する際、f.submitだとlogoが表示できず
例えばbutton_tagを利用すると= button_tag type:'submit', class: 'submit_btn' do = icon('fas','search')と使用することで、ロゴのボタンを使用することができる。
またこちらのロゴを使用する際はFontAwesomeをgemファイルからインストールするgem 'font-awesome-sass'こちらを入力してbundle install
またapplication.scssに
@import "font-awesome-sprockets"; @import "font-awesome";を入力するのを忘れずに。
- 投稿日:2020-07-31T14:21:20+09:00
NoMethodError: undefined method `paginate' for を解決する (Railsチュートリアル 10章)
発生しているエラー
Railsチュートリアル10章 10.3.3 ページネーション
Gemfilegem 'will_paginate', '3.1.6' gem 'bootstrap-will_paginate', '1.0.0'$ bundle installそしてチュートリアルの指示通りにコードを追記し、
$ rails testを実行すると、
Error: UsersIndexTest#test_index_including_pagination: NoMethodError: undefined method `paginate' for #<Class:0x00007fb0253e5c60> app/controllers/users_controller.rb:6:in `index' test/integration/users_index_test.rb:14:in `block in <class:UsersIndexTest>'というエラーが発生する。
対処法
$ spring stopこれを実行すると解決する。
参考:RAILS_ENV=test時のみ、paginateメソッドがundefinedになる
springとは
Spring は Rails アプリケーションの preloader(プリローダー)の gem です。(pre + load = 前もってロードしておく)
今回はロードを勝手にしてくれるspringによる影響でエラーが発生していたようですね。
詳しく説明できる方は、コメントで補足していただけると幸いです。
役に立ったら是非LGTMボタンをポチッと押していただけると嬉しいです。
一緒に Rails学習 頑張りましょう!
- 投稿日:2020-07-31T12:49:51+09:00
【初学者向け】Route53でドメイン取得してポートフォリオに紐つける手順
前提条件
EC2でアプリをデプロイしている事
→もしまだデプロイ出来ていないのならこちらの記事を参考にしてください。私も同じ様にやってきました。手順
他にも沢山の参考記事がある為そちらを参考にしましたが、ドメイン取得に関してはこちらの記事で問題なく出来ます。
ただしこの記事にもある様にnginxで確実にエラーが出ます。
なので、デプロイの時と同様に
[name(自分の名前)|~]$cd /etc/nginx/conf.d/ [name(自分の名前)|conf.d]$ sudo vi ◯◯.conf #自分のアプリ名# log directory error_log /var/www/rails/〇〇/log/nginx.error.log; #自分のアプリケーション名に変更 access_log /var/www/rails/〇〇/log/nginx.access.log; #自分のアプリケーション名に変更 # max body size client_max_body_size 2G; upstream app_server { # for UNIX domain socket setups server unix:/var/www/rails/mumu/tmp/sockets/.unicorn.sock fail_timeout=0; #自分のアプリケーション名に変更 } server { listen 80; server_name ~~~.~~~.~~~.~~~;(#アプリのElastic IPに変更してください)←ここを取得したドメインに書き換えてください # nginx so increasing this is generally safe... keepalive_timeout 5; # path for static files root /var/www/rails/〇〇/public; #自分のアプリケーション名に変更 # page cache loading try_files $uri/index.html $uri.html $uri @app; location @app { # HTTP headers proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } # Rails error pages error_page 500 502 503 504 /500.html; location = /500.html { root /var/www/rails/〇〇/public; #自分のアプリケーション名に変更 } }保存出来たらnginxを再起動します。
[name(自分の名前)|conf.d]$ cd /var/www/rails/〇〇 #自分のアプリ名 [name(自分の名前)|〇〇]$ sudo service nginx restart Stopping nginx: [ OK ] Starting nginx: [ OK ]こうなっていれば大丈夫です!
後は取得したドメインを検索し問題なくサイトを開けるか確認してください!SSL化について
【初学者向け】AWSでSSL化する方法に記載しています。
- 投稿日:2020-07-31T12:35:28+09:00
resourcesとresourceを組み合わせて使う時の注意点についてまとめてみた
先日、resourcesとresourceの違いについてまとめてみましたが、組み合わせて使う際の注意点もあったのでまとめてみました。
違いについてはこちら → resourcesとresourceの違い - Qiitaresourcesとresourceを組み合わせて使う場合
resourcesとresourceを組み合わせて使うと、下記のようなルーティングが簡単に生成できます。
- 全ユーザーの一覧表示
- 全ユーザーの詳細表示
- 自ユーザーの詳細表示
- 自ユーザー情報の編集
全ユーザー一覧、各ユーザーの詳細については、誰でも表示できるが、ユーザー情報の編集は自分のものしかできないという状態。
config/routes.rbresources :users, only: [:index, :show] resource :user, only: [:show, :edit, :update]
rails routes
で生成されたルートを確認すると、下記のような感じ。ターミナルPrefix Verb URI Pattern Controller#Action users GET /users(.:format) users#index user GET /users/:id(.:format) users#show edit_user GET /user/edit(.:format) users#edit GET /user(.:format) users#show PATCH /user(.:format) users#update PUT /user(.:format) users#update
user GET /users/:id(.:format) users#show
の部分、user_pathが/users/:idに割り当てられてしまうことで、/userを返すべきヘルパーメソッドが生成されない。
ということで、順番を逆にして記載してみた。config/routes.rbresource :user, only: [:show, :edit, :update] resources :users, only: [:index, :show]
rails routes
で生成されたルートを確認すると、下記のような感じ。ターミナルPrefix Verb URI Pattern Controller#Action edit_user GET /user/edit(.:format) users#edit user GET /user(.:format) users#show PATCH /user(.:format) users#update PUT /user(.:format) users#update users GET /users(.:format) users#index GET /users/:id(.:format) users#show自ユーザーは、ログイン機能(session管理)で特定できれば、リクエストに:idを含む必要はないので、自ユーザーに関するルーティングは
resource
を使用しています。自分以外のユーザーの詳細画面を見るには、対象となるユーザーのIDを指定する必要があるので、
resources
でリクエストに:idを含むルートを生成しています。結論
単数形で使用する
resource
と、複数形で使用するresources
を組み合わせてルーティングを作る際は、単数形のresource
を上に書くようにする。
- 投稿日:2020-07-31T11:39:37+09:00
Rails 本番環境で画像が読み込まれないエラー
この記事について
本番環境でbackground-imageの画像を読み込む時にはエラーが出ないのに、image_tagのところだけでエラーが出てしまっていたので、そのエラー解決方法について
環境
・Ruby 2.6.6, Rails 6.0.3.2
・Docker,Docker-compose(開発環境)
・AWS/本番環境(EC2, RDS, VPC, EIP, Route53, IAM, S3)参考URL
https://stackoverflow.com/questions/49440304/rails-asset-is-not-present-in-asset-pipeline-when-using-image-tag
この人と全く同じ現象になってました。出ていたエラー
qiita.rbActionView::Template::Error (The asset "chat_example.jpeg" is not present in the asset pipeline.):asset へのパイプラインがうまくいっていない様子
解決方法
config/environments/production.rbにある、config.assets.compile = falseをtrueに変えてあげる。
config/environments/production.rb- config.assets.compile = false + config.assets.compile = true
- 投稿日:2020-07-31T11:15:58+09:00
Controller作成と同時にアクションとviewファイルを作成(rails)
Controller作成と同時にアクションとviewファイルを作成
railsではcontrollerを作成する際、同時にアクションとviewファイルを作成することができます。
実際に手動でアクションやviewファイルを作成する手間を省くことができます。
以下がコマンドの型です。$ rails g controller コントローラ名 アクション名例えば、book controllerを作成し、newアクションを追加したい場合、、、
$ rails g controller book newこんな感じになれば、成功。
[vagrant@localhost sample_app]$ rails g controller books new Running via Spring preloader in process 25819 create app/controllers/books_controller.rb route get 'books/new' invoke erb create app/views/books create app/views/books/new.html.erb invoke test_unit create test/controllers/books_controller_test.rb invoke helper create app/helpers/books_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/books.coffee invoke scss create app/assets/stylesheets/books.scss
- 投稿日:2020-07-31T10:58:03+09:00
カラムの追加と削除
カラムとは?
カラムとはデータベースの中のテーブルが持つ要素です。
例えば、ユーザーというテーブルの中の「名前、生年月日、住所」などの項目をカラムと言います。カラムの追加
新たに別のカラムを追加したいということはよくあると思います。
そんなときは以下のコマンドでカラムを追加です。$ rails g migration Addカラム名Toテーブル名 カラム名:型名例えば、「User」というテーブルに「name」というカラムを追加したい場合、
$ rails g migration AddNameToUsers name:string $ rails db:migrateここで「rails db:migrate」を忘れてしまうと、テーブルへ反映されませんので、
気をつけてください。カラムの削除
カラム名を間違えて登録した時など、カラムを削除したいこともあると思います。
カラムを追加する時とあまり変わりません。$ rails g migration Removeカラム名Fromテーブル名 カラム名:型名「User」というテーブルの「name」というカラムを削除したい場合、
$ rails g migration RemoveNameFromUsers name:string $ rails db:migrateここでも「rails db:migrate」は忘れずに。
- 投稿日:2020-07-31T10:41:22+09:00
[Rails] ActiveModel::Attributesの使い方(配列化やネストしたhashの取り扱いなども)
ActiveModel::Attributesの使い方について使い方をまとめてみたいと思います。他の方の記事も少しだけありましたが、配列の作り方とか、ネストしているhashをオブジェクト化するやり方があまりまとまってなかったので初投稿してみることにしました。
サマリ
記事の下まで読むと、ネストしているhashをActiveModel::Attributesを使ってきれいにオブジェクト化することができます。こんな感じです。
hash = {name: "徒然草", price: 1000, authors: [{name: "兼好法師", age: 35}, {name: "健康男児", age: 20}]} book = Book.new(hash) book.name # => "徒然草" book.authors.class # => Array book.authors.first.class # => Author book.authors.first.name # => "兼好法師" book.authors.first.age # => 35なお、ActiveModel::Attributesとはなにかについては触れません。あとバリデーションについても触れてません。
この記事で書くこと
- 基本的な書き方
- hashを渡してインスタンス生成
- カスタムタイプを使う
- array型を作る
- ネストしたインスタンスを生成する
基本的な書き方
ActiveModel::Attributesを使うためには自分で作ったclassにActiveModel::Modelと一緒にincludeして使います。
class Book include ActiveModel::Model include ActiveModel::Attributes end属性(attribute)を定義する
クラスに持たせる属性を定義します。
class Book include ActiveModel::Model include ActiveModel::Attributes attribute :name, :string attribute :price, :integer, default: 100 attribute :createdate, :datetime enddefaultを設定すると、インスタンス生成した際のデフォルト値を設定できます。
標準で使用できる型
「
:string
などの型っぽいのがシンボルで渡されているけど、これはなに?」と思うと思います。これはActiveModel::Typeのなかで事前に定義されている型です。ActiveModel::Attributesでは、ActiveModel::Typeの型を使う必要があります。基本的な型はそろっていますが、これ以外の型を使いたい場合はカスタムタイプを自分で定義する必要があります。(後述)
デフォルトで使える方は以下の通り。:big_integer -> BigInteger型 :binary -> Binary型 :boolean -> Boolean型 :date -> Date型 :datetime -> DateTime型 :decimal -> Decimal型 :float -> Float型 :immutable_string -> ImmutableString型 :integer -> Integer型 :string -> String型 :time -> Time型Railsのコードのこちらにregisterメソッドで定義しています。
hashを渡してインスタンス生成
基本的な使い方はこのclassにhashを渡してあげてインスタンスを生成する形です。JSONデータをパースしてそのまま放り込むとオブジェクトが生成できるので便利です。
class Book include ActiveModel::Model include ActiveModel::Attributes attribute :name, :string attribute :price, :integer, default: 100 attribute :createdate, :datetime end book = Book.new({name: "徒然草", price: 200, createdate: '1993-02-24T12:30:45'}) book.class # => BookちゃんとBookクラスのインスタンスが生成できています。attributeは
.
をつけて呼び出せます。book.name # => "徒然草" book.price # => 200 book.createdate # => 1993-02-24 12:30:45 UTC book.createdate.class # => Timeここでdefaultも試してみます。
price
をhashに含めないでインスタンスを生成するとbook = Book.new({name: "徒然草", createdate: '1993-02-24T12:30:45'}) book.price # => 100ちゃんとデフォルト値が入ります。逆にattributeにないものを入れようとすると、
book = Book.new({name: "徒然草", createdate: '1993-02-24T12:30:45'}, author: "aa") # ArgumentError (wrong number of arguments (given 2, expected 0..1))エラーになります。
attributesメソッド、attribute_namesメソッド
attributes
メソッドで定義されている属性全てがhashで取得できます。book.attributes # => {"name"=>"徒然草", "price"=>100, "createdate"=>1993-02-24 12:30:45 UTC}また、attribute_namesで属性の名前だけを配列で取得できます。(Rails 6.0.0以降の場合のみ)
book.attribute_names # => ["name", "price", "createdate"]カスタムタイプを使う
ここから応用編です。デフォルトで用意されている型ではないものを使いたい時はカスタムタイプを定義します。例えば以下のようなauthor属性を追加してみたいとします。
class Book include ActiveModel::Model include ActiveModel::Attributes attribute :name, :string attribute :price, :integer, default: 100 attribute :createdate, :datetime attribute :author_name, :author end
:author
は元々定義されているものではないので自分で型を作ります。models/type_author.rb# models/type_author.rbを新規作成 class TypeAuthor < ActiveModel::Type::String def cast_value(value) "吾輩は" + value + "である" end endconfig/initializers/types.rb# config/initializers/types.rbを新規作成 ActiveModel::Type.register(:author, TypeAuthor)これで定義完了。実際に使ってみます。
book = Book.new({name: "徒然草", price: 200, createdate: '1993-02-24T12:30:45', author_name: "兼好法師"}) book.author_name # => "吾輩は兼好法師である"何をしたかと言うと、
TypeAuthor
クラスはActiveModel::Type::String
クラスを継承していて、ActiveModel::Type::String
クラスにあるcast_value
メソッドをオーバーライドしています。
インスタンス生成する際にsetterがこのメソッドを呼び出して、cast_value
メソッドの戻り値が属性にセットされる形になります。Array型を作る
属性に配列を持たすこともできます。先ほどのTypeBookクラスを改良してみます。
ActiveModel::Type::Value
クラスは先程使ったActiveModel::Type::String
クラスの親クラスで、受け取った値をそのままsetする型です。models/type_author.rb# models/type_author.rb class TypeAuthor < ActiveModel::Type::Value def cast_value(value) value end endconfig/initializers/types.rbActiveModel::Type.register(:author, TypeAuthor)単純に受け取った値をそのまま返すだけにして、
author_name
をauthor_names
にして配列を受け取ります。この状態でauthor_namesに配列を渡してみるとどうなるでしょうかclass Book include ActiveModel::Model include ActiveModel::Attributes attribute :name, :string attribute :price, :integer, default: 100 attribute :createdate, :datetime attribute :author_names, :author end book = Book.new({name: "徒然草", price: 200, createdate: '1993-02-24T12:30:45', author_names: ["兼好法師", "健康男児"]}) book.author_names # => ["兼好法師", "健康男児"]ちゃんと配列が格納されています。
ネストしたインスタンスを生成する
最後に属性に別のインスタンスの配列を持たせるような形にできないでしょうか。例えば、Bookクラスの属性としてAuthorクラスの配列が含まれているもの。hashにするとこんな元データです。APIで受け取ったJSONデータとかよくこのような形になっていますよね。
{ name: "徒然草", price: 1000, authors: [ {name: "兼好法師", age: 35}, {name: "健康男児", age: 20} ] }兼好法師と健康男児はAuthorクラスのオブジェクトとして生成し、
authors
の属性として配列で持つというケースです。これはどうやってやるかというと、今までの説明の全てを駆使してやります。models/book.rbclass Book include ActiveModel::Model include ActiveModel::Attributes attribute :name, :string attribute :price, :integer, default: 100 attribute :authors, :author_array, default: [] endmodels/author.rbclass Author include ActiveModel::Model include ActiveModel::Attributes attribute :name, :string attribute :age, :integer endmodels/type_author_array.rbclass TypeAuthorArray < ActiveModel::Type::Value def cast_value(value) arr = [] value.each do |v| arr.push Author.new(v) end arr end end # config/initializers/types.rb ActiveModel::Type.register(:author_array, TypeAuthorArray)ポイントとしては型のキャストをする
TypeAuthorArray
クラスでAuthor
クラスのインスタンスを生成して、配列に格納してBookクラスのインスタンスにセットしてあげる部分です。
早速使ってみましょう。hash = {name: "徒然草", price: 1000, authors: [{name: "兼好法師", age: 35}, {name: "健康男児", age: 20}]} book = Book.new(hash) book.authors.class # => Array book.authors.first.class # => Author book.authors.first.name # => "兼好法師"素晴らしい。ちゃんと
authors
属性にAuthor
クラスのインスタンスの配列が格納されていて、Authorクラスの属性を呼んであげると、値が取得できました。最後に
APIでJSONファイルを受け取った後、Modelのオブジェクトと同じように扱いたい場合はActiveModel::Attributeでインスタンスを作ってあげればいろんなことがよしなにできるようになります。
誰かの一助となれば幸いです。
- 投稿日:2020-07-31T09:40:32+09:00
【Rails】エラー解決 Unsupported argument type: 1 (Integer)
はじめに
今回は
Unsupported argument type: 1 (Integer)
こんなこと言われた時の対処方を記述します
お決まりのタイプミスによって発見したエラー文です笑解決策
intger型の1という引数は期待してません、という感じのエラー文です。
という事は違う物を期待してるところで整数の1を渡してしまっているという事です。
User.find_by(session[:user_id])犯人はこれでした!
find
と書くべきところを間違えてfind_by
と書いてますね、なのでfind_by
のカラム名を書くところにsession[:user_id]
が入っているせいで、今回は[1]という整数が入ってるのでそのまんま[1]って名前のカラムを探しに行こうとしてしまった、そんな感じみたいですね。↓こんな感じの事ですね!
User.find_by(1)という事で
User.find(session[:user_id])
find
に書き換えて解決!学び
find
をfind_by
と間違えると高確率でUnsupported argument type: ... (Integer)
が出ると思うのでこんな感じのエラーを見かけたらfind
周りチェックするのがいいかもですね!
- 投稿日:2020-07-31T01:19:33+09:00
herokuのエラー
- 投稿日:2020-07-31T01:03:28+09:00
railsでmodelを作成する方法
railsでmodelを作成する方法
modelはデータベースとのやりとりを行ってくれます。
modelを作成するコマンドはこんな感じです。$ rails g model モデル名モデル名の命名規則は、「User」のように、英数字の単数形で指定します。
また、先頭は必ず英大文字で記述します。実際に、modelを作成するためのコマンドを打つとこんな感じです。
$ rails g model User成功すると、、、
$ rails g model User Running via Spring preloader in process 4271 invoke active_record create db/migrate/2020072951856_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml作成されるファイルは以下の4つです。
db/migrate/(作成日時)create_lists.rb:「マイグレーションファイル」というデータベースの設計図になるファイルです。
app/models/list.rb:モデルクラスはデータベースに対応したRubyのクラスです。
test/models/listtest.rb:モデルクラスのテストコードのひな形です。
test/fixtures/lists.yml:テストデータ作成のためのひな形です。
- 投稿日:2020-07-31T00:44:25+09:00
railsでルーティングを設定する方法
railsでルーティングを設定するには
routing(ルーティング)では、ユーザが特定のURLにアクセスした時に、
どのコントローラのどのアクションに処理を振り分けるかを定義します。
ルーティングは、URLとアクションを結びつける役目をしています。
例えば、「あるURLにアクセスがあった時に、homeコントローラのtopアクションの処理を振り分ける」という定義を、ルーティングに記述します。ルーティングの設定は、configフォルダ内のroutes.rbファイルに記述します。
routes.rbファイルは、Railsアプリを作成するときに自動作成されるファイルです。
こんな感じです。HTTPメソッド 'URL' => 'コントローラ#アクション'※HTTPメソッドについてはこちらの記事で説明しています。
https://qiita.com/yusuke1209kitamura/items/e29787bc2920a656d505わかりやすく、実際に書いてみます。
Rails.application.routes.draw do get 'top' => 'homes#top' endこの例の場合、URL「top」にアクセスすると、
homesコントローラのtopアクションが呼び出されるように設定しています。
- 投稿日:2020-07-31T00:28:59+09:00