20211230のRailsに関する記事は10件です。

【Rails × Vue】本番環境で画像が読み込めないエラー対応

AWSにデプロイしたRailsとVueで作成したポートフォリオにおいて画像が表示されないエラーが発生し、解決したのでその方法です。 修正前のディレクトリツリー original_app | |--app | | | |--assets | | | |--images | | | |--img1.svg | |--src | |--pages | |--Home.vue #このコンポーネントでimg1.svgを読み込みたい Home.vue <template> <img src="/assets/img1.svg"> </template> 開発環境だとing1.svgを読み込めたが本番環境だとうまくいかなかった。 原因 通常のrailsアプリであればviewファイルに/assets/画像ファイルと書けばassets以下のimagesフォルダからファイルを探してきてくれるがVueのファイルはjavascriptなのでそのような動作をしてくれなくなる。 修正後のディレクトリツリー original_app | |--app | |--src | |--assets #追加 | | | |--img1.svg | | |--pages | |--Home.vue #このコンポーネントでimg1.svgを読み込みたい Home.vue <template> <img src="../assets/img1.svg"> </template> 画像ファイルをvueファイルをまとめているフォルダ内に収納してし、直接参照できるようにしてしまう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails generateコマンドまとめ

rails generateコマンド モデルの作成 コマンド rails generate model 名前 [カラム名:型[:index]..] [オプション] 結果 invoke active_record create db/migrate/20211230082754_create_<名前>s.rb create app/models/<名前>.rb invoke test_unit create test/models/<名前>_test.rb create test/fixtures/<名前>s.yml 参考 Railsドキュメント コントローラーの作成 コマンド rails generate controller 名前 [アクション名..] [オプション] 結果 create app/controllers/<名前>_controller.rb route get '<名前>/new' invoke erb create app/views/<名前> create app/views/<名前>/new.html.erb invoke test_unit create test/controllers/<名前>_controller_test.rb invoke helper create app/helpers/<名前>_helper.rb invoke test_unit invoke assets invoke scss create app/assets/stylesheets/<名前>.scss 参考 Railsドキュメント メイラーの追加 コマンド rails generate mailer 名前 [アクション名..] [オプション] 結果 create app/mailers/<名前>.rb invoke erb create app/views/<名前> create app/views/<名前>/password_setting.text.erb create app/views/<名前>/password_setting.html.erb invoke test_unit create test/mailers/<名前>_test.rb create test/mailers/previews/<名前>_preview.rb 参考 Railsドキュメント 統合テストの追加 コマンド rails generate integration_test 名前 結果 invoke test_unit create test/integration/register_employee_test.rb 参考 Railsドキュメント コマンド 結果 参考 Railsドキュメント コマンド 結果 参考 Railsドキュメント コマンド 結果 参考 Railsドキュメント コマンド 結果 参考 Railsドキュメント
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Railsのcloud9環境の設定手順

Rails Tutorialより Rubyドキュメントをスキップする設定を.gemrcファイルに追加するコマンド echo "gem: --no-document" >> ~/.gemrc Rails gemのインストール(今回は6.1.4を使用) Railsバージョンアップ情報 gem install rails -v バージョン番号 bundler gemのインストール(今回は2.2.17を使用) gem install bundler -v バージョン番号 Yarnのインストール、セットアップ source <(curl -sL https://cdn.learnenough.com/resize) source <(curl -sL https://cdn.learnenough.com/yarn_install) ローカルWebサーバーへの接続の許可 config/environments/development.rb Rails.application.configure do . . . # Cloud9 への接続を許可する config.hosts.clear end Gemfileの設定+bundleの実行 参考記事:Gemfileにバージョンを指定したり、しなかったり。Gemfileについて # production環境でしか使わないgemはインストールしないよう設定 bundle _2.2.17_ config set --local without 'production' bundle _2.2.17_ install webpacherのインストール rails webpacker:install Gitの操作 Gitの設定 git config --global user.name "自分の名前" git config --global user.email your.email@example.com # パスワードの再入力をしなくていい時間を設定 git config --global credential.helper "cache --timeout=86400" # エイリアスメソッドを設定 git config --global alias.<エイリアス名> コマンド Githubへの初めてのプッシュ git init git add -A git commmit -m "<コメント>" git remote add origin <uri> git push -u origin master
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Heroku(PostgreSQL)のDBリセット方法

はじめに プログラミング初学者の@kat_logと申します。 Heroku(PostgreSQL)で間違えたレコードを登録した時など、DBを一旦リセットする方法の共有です。 (学習中のため、自分へのメモ的な意味もあります?) 結論 下記コマンドの実行で可能です。 heroku pg:reset DATABASE その後、 heroku run rails db:migrate にて再びマイグレートできます。 おわりに お読みいただきありがとうございました。 自分と同じく初学者の参考になれば嬉しいです。 一緒に頑張っていきましょう〜?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsでGraphQLサーバー構築体験??

一応 RailsでWeb APIを作成する方法とメリット?? の記事の続きですが前回の記事を読んでいなくても構築可能です。 RailsでGraphQLサーバーを立ち上げて基本的なQuery、Nutation機能を実装してみました! 前提 GraphQLをある程度知っていないとコードの理解は困難です。m(_ _)m GraphQLが何なのかは説明しません。ある程度、GraphQLがどういうものかを知っている前提で進めます。 ぜひ公式サイトなどで仕様をご参照ください。 HTTP リクエストメソッドについては説明しません。 MDNをぜひ (https://developer.mozilla.org/ja/docs/Web/HTTP/Methods) HTTPリクエストボディの説明はしていません。 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 このサイト初心者向けに用語説明しててわかりやすいです。 DBにbooksテーブルがある状態で始めます。 先ほどのstringのtitle, textのbodyカラムを持ったテーブルです。 RailsをGraphQLサーバーにするには? 今回は、まずRailsをAPIモードを用意します。(前回の記事で用意しています。) 完成版ソースコードもあります。 その後、Gem graphql-ruby をGemfileに記載してbundle installしてGraphQLサーバー化していきます。 APIサーバーは既に用意しているのでGemをインストールするところから進めます。 RailsでGraphQLサーバーを作成していきます Gemfileで以下を追記し、installします。 gem 'graphql' $ bundle install GraphQLのテンプレートを生成します。以下のコマンドを実行するとGraphQL関連のファイル群が生成されます。 $ rails g graphql:install Running via Spring preloader in process 35807 create app/graphql/types create app/graphql/types/.keep create app/graphql/graphql_server_sample_schema.rb create app/graphql/types/base_object.rb create app/graphql/types/base_argument.rb create app/graphql/types/base_field.rb create app/graphql/types/base_enum.rb create app/graphql/types/base_input_object.rb create app/graphql/types/base_interface.rb create app/graphql/types/base_scalar.rb create app/graphql/types/base_union.rb create app/graphql/types/query_type.rb add_root_type query create app/graphql/mutations create app/graphql/mutations/.keep create app/graphql/mutations/base_mutation.rb create app/graphql/types/mutation_type.rb add_root_type mutation create app/controllers/graphql_controller.rb route post "/graphql", to: "graphql#execute" Skipped graphiql, as this rails project is API only You may wish to use GraphiQL.app for development: https://github.com/skevy/graphiql-app create app/graphql/types/node_type.rb insert app/graphql/types/query_type.rb create app/graphql/types/base_connection.rb create app/graphql/types/base_edge.rb insert app/graphql/types/base_object.rb insert app/graphql/types/base_object.rb insert app/graphql/types/base_union.rb insert app/graphql/types/base_union.rb insert app/graphql/types/base_interface.rb insert app/graphql/types/base_interface.rb insert app/graphql/graphql_server_sample_schema.rb Object typeを定義 Object typeはどういう形のデータをreturnするかを決めるものです。 $ rails g graphql:object Book Running via Spring preloader in process 97118 create app/graphql/types/book_type.rb app/graphql/types/book_type.rb というファイルが作成されます。 ファイルを開くと以下の様にfieldが定義されているはずです。 *Bookモデルを作成していると、自動でfieldが定義されます。 app/graphql/types/book_type.rb module Types class BookType < Types::BaseObject field :id, ID, null: false field :title, String, null: true field :body, String, null: true field :created_at, GraphQL::Types::ISO8601DateTime, null: false field :updated_at, GraphQL::Types::ISO8601DateTime, null: false end end Queryを定義 app/graphql/types/query_type.rb module Types class QueryType < Types::BaseObject # bookのデータがあれば[本の情報、本の情報, ...]という形式でデータを返します。 # 角括弧内でnull: trueしているので空の[ ]を返してもOKにしてます。 # null: falsede必ずデータは何かしら返さなきゃいけないようにしています。(なかったらエラー) field(:books, [BookType, null: true], null: false) do description 'fetch all books' end # bookのデータを一つ返すようにしています。 # null: falseなので必ずデータ返さなきゃいけないようにしてます。(なかったらエラー) field(:book, BookType, null: false) do description 'find a book by id' argument :id, ID, required: true end def books Book.all end def book(id:) Book.find(id) end end end これで実際にデータを取得する準備が整いました。実際にAPIの開発ツールを使って検証してみましょう。 Gem graphiql-railsを使ってGraphiqlなどでも確認できますが個人的にPostmanが好きなのでPostmanで確認します。 PostmanはAPI開発の手助けをしてくれるツールです。 URIを指定して通信リクエストを実行してどういうデータが返ってくるかなぁ〜とか色々確認ができるわけです。 早速、GraphQLのQueryを指定してデータが取得できるかどうがみてみましょう。 Queryを実行 rails s でサーバーを起動します。 HTTP verbを POSTにします。 GraphQLのラジをボタンを選択します。 HTTP リクエストメッセージボディクエリを記述します。 別のクエリでGraphQLにデータ要求してみましょう。 id 1のbookのtitleだけを取得します。 複数のクエリを一度に実行してみましょう。 すべてのbookのidと、id 1のbookの全ての情報を取得してみます。 このように、クエリがどんなデータを返却してくれるのかが直感的にわかりますね! さらに、必要なデータだけに絞って取得することもできたので過剰に無駄なデータ取得することも無くなります。 Mutationを定義 先ほどはデータの取得はQueryで行いましたが、データの作成、更新、削除はMutationというもので行います。 データを作成して、取得するという機能を制作していきます。 今回はbookのcreate(作成用)のmutationを定義していきます。 以下を実行して、create_bookというmutationを実装していきます。 $ rails g graphql:mutation create_book Running via Spring preloader in process 61114 exist app/graphql/mutations identical app/graphql/mutations/.keep identical app/graphql/mutations/base_mutation.rb identical app/graphql/types/mutation_type.rb add_root_type mutation create app/graphql/mutations/create_book.rb gsub app/graphql/types/mutation_type.rb app/graphql/mutations/create_book.rb というファイルが作成されているのがわかります。 以下の様に、変更してみます。 app/graphql/mutations/create_book.rb module Mutations class CreateBook < BaseMutation # 返却されるデータの形を定義しています。 field :book, Types::BookType, null: false # GraphQL Variableの情報を定義してます。 # これがないと作成時の情報も利用できないです。 argument :body, String, required: true argument :title, String, required: true # Resolverで返却したいデータをreturnします。 def resolve(**attributes) # attributesには次のHashが渡ってきます。(attributesという名前以外でもOKです。) # {:body=>"GraphQL理解しないとGraphql-rubyわからんね", :title=>"GraphQLな奴"} book = Book.create!(attributes) { book: book } # このデータが返却されます。(Rubyはreturn省略できます。) end end end field :book, Types::BookType, null: falseと定義していますがこれは最終的に 以下の様なデータが返ってきます。 { "data": { "createBook": { book: { "title": "GraphQLな奴", "body": "GraphQL理解しないとGraphql-rubyわからんね" } } } } Mutationを実行 ところで、以下の様にデータを受け取りたい場合はどうするでしょうか? { "data": { "createBook": { "title": "GraphQLな奴", "body": "GraphQL理解しないとGraphql-rubyわからんね" } } } 返却されるデータの形はfieldで定義されていました。 なので返却されるfieldを変えてしまえばいいわけです。 app/graphql/mutations/create_book.rb module Mutations class CreateBook < BaseMutation # 既にapp/graphql/types/book_type.rbで定義しているfield群を利用します。 # その場合はfieldではなくてtypeで呼び出します。 type Types::BookType argument :body, String, required: true argument :title, String, required: true def resolve(**attributes) Book.create!(attributes) end end end 実際にクエリするとこんな感じ コードの流れをざっくり説明していきます。 Mutationが GraphQL::Schema::RelayClassicMutation を継承してると、デフォルトでInput objectが自動で定義されるようになっています。クエリにもinput型の定義が必要になります。(GraphQL Rubyの仕様です。) input型を定義して、それに相当するデータもGraphQL Variableに指定してクエリを実行します。 input型はストロングパラメーターの型があるパージョンと言えばRails触ってる人はわかりやすいかな...? ?? fieldで定義した通りのデータがResolverから(resolveメソッドから)返ってきます。 最終的にデータを返すメソッドがresolveです。Resolverとか呼ばれてる奴です。 今回はbookのtitleとbodyだけを取得するようにしているので、title, bodyの情報が返ってきました。 クエリ実行時のfieldには、title, bodyだけ指定しているのでそれ以外のデータは返ってきませんね。 結構色々定義して面倒だと思われた方!!! 仮にですが、input型の指定無しでクエリ実行したい! という方は GraphQL::Schema::RelayClassicMutation を継承させないようにすればOKです。 app/graphql/mutations/create_book.rb module Mutations # 継承元を変更します。 class CreateBook < GraphQL::Schema::Mutation field :book, Types::BookType, null: false argument :title, String, required: true argument :body, String, required: true def resolve(**attributes) book = Book.create!(attributes) { book: book } end end end この状態でクエリを実行すると以下のようにinput型の指定無し、GraphQL Variableの指定無しでクエリの実行ができました。 しかし、input型がある方がストロングパラメーターみたいに使いまわせたり、型の面で便利なので、本当はinput型を使っていた方がいいと思います。 GraphQLの何がよいの??? これまでQuery、Mutationでデータの取得、作成を行ってきました。 GraphQLのいいところはやはり直感的にどういうデータが返ってくるかが分かりやすい。 データの型も指定できるのでどういう型のデータが来るかも分かりやすいです。 本当に必要な必要最小限のデータだけを柔軟に取得できる クエリ実行時にbookのidだけ必要であればクエリのfieldにidだけ書けば良いのです。 一つのエンドポイントで、かつ一度のリクエストで色々なデータにアクセス可能 この記事では全データの取得、データの一つを取得、データの作成をたった一つのエンドポイントで成し遂げました。 http://localhost:3000/graphql だけでやりとげました。たくさんRouting定義しなくてもいいわけです。 クエリは一度に複数指定も可能でした。 他にも色々メリットがありますがそんなAPIサーバーが作成をしていきました。 フロントエンドからどうやってクエリ実行すれば良いの? Apollo ClientとかGraphQLに特化したライブラリを使うと良いです。 ライブラリを使わなくともPOSTメソッドなHTTPリクエストのボディにクエリを持たせているだけですのでFetch APIやAxiosを使ってリクエストボディにクエリを含ませれば実行できます。 要は、HTTPリクエストができればクエリは実行できるわけです。 Apollo Clientもまとめてみたいのですが記事の範疇を超えるので割愛します。m(_ _)m 素敵なAPI、GraphQLライフを٩(ˊωˋ)و✧
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】モデルにインスタンスメソッドを定義する方法

モデルにメソッドを定義する理由 モデルに書くのはvalidatesやbelongs_to,has_manyなどだけでなく、メソッドも定義できる。 もちろんモデルを使わなくても小さいサービスであればコントローラーでも全然問題ないが、 理由として少し大きなサービスになってくると、すぐにコントローラーのコード量が増えてしまうからである。(ファットコントローラー) その時は理解できても、数ヶ月後にコードを見返すと何のコードなのかわからなくなってしまう可能性がある。 例を交えて解説 user_controller.rb def index @user = User.find(1) @my_age = @user.too_young ⬅️ end このtoo_youngがインスタンスメソッドというもので、モデルで書いたメソッドを コントローラーで呼び出している。 user.rb class User < ApplicationRecord validates :username, presence: true validates :email, presence: true #ここがインスタンスメソッド def too_young if self.age >= 20 #20歳以上の場合 return "大人です!" else #20歳以下の場合 return "子供です!" end end end too_youngメソッド内に「self」というものがある。 この「self」は何かというとusers_controller.rbで定義された@userのこと。 @userというインスタンスに対して「.(ドット)」で繋げてインスタンスメソッドを呼び出す時、インスタンスメソッド内では「self」が使え、self=呼び出し元のインスタンス(@user)となる。 インスタントメソッド内のselfは省略可能。 インスタントメソッドとは インスタンスメソッドとは、作成したインスタンスから実行出来るメソッドのこと。 initializeメソッドでインスタンス変数に代入し、情報を保持している。 インスタンスメソッドは、このインスタンスごとに保持している情報を使って処理を書くことが出来る。 インスタントメソッドとは別にクラスメソッドがあるが、使い分けはクラスメソッドは全体で扱うべき情報を扱い、インスタンスメソッドは個々で扱うべき情報を扱うことを認識しておけばいい。 参考記事 Railsのモデルに書いたメソッドってどうやってコントローラで使うの? 【Ruby】 たい焼きで理解するオブジェクト指向におけるクラスの概念 【Ruby基礎】クラスメソッドとインスタンスメソッドの違いについて簡単にまとめてみた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】セレクトボックスを作る方法と注意点【select・collection_select】

Railsのセレクトボックスって、 引数の順番とか指定できる項目の種類が ごちゃごちゃしてて、なんとなーくの理解だったので、 色々調べてみました! なお、間違いやもっと良い方法がある...等ありましたら、 お気軽にコメントください。お願いいたします! 作成方法①:select メソッド select メソッドを使ったセレクトボックスの構文は下記です。 select(オブジェクト名, オプションタグの要素(配列 or ハッシュ), オプション, HTMLオプション) まず、コントローラーでselect に渡す要素を準備する必要があります。どのような方法でも良いですが、例として下記のような取得方法があるでしょう。 app/controllers/user_controller.rb @users = User.pluck(:name, :id) # => [["A太郎", 1], ["B太郎", 2], ["C太郎", 3]] @users = User.all.map { |user| [ user.name, user.id ] } # => [["A太郎", 1], ["B太郎", 2], ["C太郎", 3]] ビュー側は以下のように書きます。 app/views/user/index.html.erb <%= f.select :id, @users, {prompt: "選択してください"}, :class => 'form-control', :id => 'user_id' %> select に指定できるオプション オプションについては、Rails ドキュメント をご覧ください。 複数選択や選択を無効化するなどの詳細な設定ができますよ! 作成方法②:collection_select メソッド【おすすめ】 collection_select メソッドを使ったセレクトボックスの構文は下記です。 collection_select(オブジェクト名, メソッド名, 要素の配列, value属性の項目, テキストの項目, オプション, HTMLオプション, イベント属性) select メソッドの際は、DBから取得したデータを select 用に加工する必要がありましたよね。 もしくは、ビュー内でDBから直接データを取得するような指定をする必要があり、 MVCの分離ができていなかったですよね。 しかし「collection_select」メソッドは加工することなく、セレクトボックスを簡単に作成できます! app/views/user/index.html.erb <%= f.collection_select :id, User.all, :id, :name, {prompt: "選択してください"}, :class => 'form-control', :id => 'user_id' %> まあ、「User.all」だってDBから直接取得してるじゃないか!! と突っ込まれたら、何も言えないのですが...。 それにしても、簡単に記述できるので、個人的にはこちらの方が使いやすいかなーといった感じです。 collection_select に指定できるオプション オプションについては、Rails ドキュメント をご覧ください。 js用のオプションを指定できるのも便利ですよね。 具体的には「onclick」イベントなどですね。 オプション指定の順番は注意! さらには、オプションの指定には注意点もあります。HTMLオプションを指定する際には、先にオプションを必ず指定しなければ、うまく動きません(引数の順番が1つずれちゃうので、当たり前と言えば当たり前なのかもですが) app/views/user/index.html.erb # これはOK <%= f.collection_select :id, User.all, :id, :name, {prompt: "選択してください"}, :class => 'form-control', :id => 'user_id' %> # これもOK <%= f.collection_select :id, User.all, :id, :name, {}, :class => 'form-control', :id => 'user_id' %> # これはNG <%= f.collection_select :id, User.all, :id, :name, :class => 'form-control', :id => 'user_id' %> 参考 【Rails】セレクトボックスを作る方法と注意点【f.select】
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】ルーティングのネストについて

ルーティングのネストとは ルーティングのネストとは、あるコントローラへのルーティングの記述の中に、別のコントローラへのルーティングを記述すること。 例えばTwitterの場合、ツイートに対してコメントできる機能があるその場合、このアプリケーションのルーティング(routes.rb)の記述は以下のようになる。 Rails.application.routes.draw do resources :tweets do resources :comments, only: [:create] end end tweetsコントローラへのルーティングの記述の中に、commentsコントローラへの記述が書かれている。こうすることによって、どのツイートに紐づいたコメントなのかをURLで判別できるようにしている。 メリット ①URLの階層構造ができる 先程のTwitterのルーティング記述により生成されるURLは、「/tweets/id/comments」になる。 もっと具体的に言うと、とあるツイートにコメントすると「/tweets/2/comments」のようなURLが生成される。この「2」という数字はツイートのid番号。 つまり、このコメントは2番のツイートに対するコメントということが、URLから判断することができる。 ②関係性のあるもの同士を紐づけることができる ツイートとコメントの関係のように、ルーティングをネストさせることによって関係性のあるもの同士をを紐づけることができる。 関係があるもの同士は、原則ルーティングをネストさせて関係性のあるURLを生成しよう モデルではこのような関係性を「has_many」と「belongs_to」で表現する 記入法 Rails.application.routes.draw do resources :親となるコントローラー do resources :子となるコントローラー ←階層を下げ、do,,,endで囲む end end 参考記事 【Rails基礎】プログラミング初学者がつまずきやすい「ルーティングのネスト」について簡単に解説 ルーティングのネスト
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Validation failed: # must exist 解決法 

はじめに Railsでポートフォリオを開発中に、rails consoleで投稿機能がしっかりデータベースに入っているかを確認した。 しかし、model.saveで実行した結果・・・ =>false という結果が出た。 データベースに保存できていない。 試したこと model.save! 上記の様に!をつけてエラーがどこにあるのかを確認できる。 そうすると・・・ ActiveRecord::RecordInvalid (Validation failed: モデル must exist) というエラーが出てきた。 モデル.rb class モデル < ApplicationRecord belongs_to :user, optional: true end optional: true をつけるだけで問題が解決した。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【 rails db:migrate実行時のエラー 】

カラムを新しく追加し、rails db:migrateを実行したが、エラー発生 deviseを導入し、ユーザー管理機能を実装していました。 login_idカラムを追加しようと思い、マイグレーションファイルにカラムを追記し、 rails db:migrateを実行したところ、 Mysql2::Error: Table 'users' already existsと表示される。 (usersテーブルは既に存在していますよ〜) なぜ? 原因はよく分からないまま、エラーをもとに検索。 結果 rails db:dorpで一度データベースを削除し、 rails db:createで再生成。 その後rails db:migrateを実行すると、エラーも無く、 login_idカラムも追加されていました。 反省 configディレクトリ内のdatabase.ymlファイルに記してある、 utf-8mb4をutf-8に変更していなかった事が原因と考えられます。 この二つではデータの保存形式が異なるそうです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む