20210911のRailsに関する記事は19件です。

railsチュートリアル第4章 組み込みクラスの変更

組み込みクラスの変更 継承を使わずにpalindrome?メソッドを直接実行できるのか? >> "level".palindrome? NoMethodError: undefined method `palindrome?' for "level":String 上のようにエラーになる。 Rubyでは組み込みの基本クラスの拡張が可能 Ruby のクラスはオープンで変更可能 クラス設計者でない開発者でもこれらのクラスにメソッドを自由に追加することが許されています。 >> class String >> # 文字列が回文であればtrueを返す >> def palindrome? >> self == self.reverse >> end >> end => :String >> "deified".palindrome? => true 真に正当な理由がない限り、組み込みクラスにメソッドを追加することは無作法 ailsの場合、組み込みクラスの変更を正当化できる理由 >> "".blank? => true >> " ".empty? => false >> " ".blank? => true >> nil.blank? => true 文字列は空(empty)とは認識されないが、空白(blank)であると認識 Railsが実はblank?メソッドをStringクラスではなく、そのさらに上の基底クラスに追加していることが推測できる 演習 1.メソッドを使い、回文かどうかを確認 >> class String >> def palindrome? >> self == reverse >> end >> end => :palindrome? >> "racecar".palindrome? => true >> "onomatopoeia".palindrome? => false クラスでメソッドを定義しなければplindrome?がエラーになる。 組み込みクラスとはこういうことだろうか? 2.クラスに新たなメソッドを追加 class String >> def shuffle >> self.split('').shuffle.join >> end >> end => :shuffle >> "irohanihoheoto".shuffle => "ihieootorhnaho" >> "irohanihoheoto".shuffle => "ihtenhhoooraoi" >> "irohanihoheoto".shuffle => "oiroiaehhoothn" 3.作成したメソッドのselfを消しても正しく動くか確かめる >> class String >> def shuffle >> split("").shuffle.join >> end >> end => :shuffle >> >> "irohanihoheoto".shuffle => "iernhthiaoooho" >> "irohanihoheoto".shuffle => "aothnhhooroiie" >> "irohanihoheoto".shuffle => "niheohoithroao" >> "irohanihoheoto".shuffle => "hraionoheohoti" 正しく動いた。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めてのGraphQL with Rails ②(Apollo Client編)

この記事の内容 前回、GraphQLの初心者がRailsでGraphQLを使えるようになるまでに調べたことをまとめて書きました。 GraphQLでデータを取得する作業のうち、 型の定義 スキーマの書き方 までは記載できたのですが、肝心の「どうやってデータを取得してくるか」が長文になりすぎて書けなかったので、ここに記載します。 参考にしたのはこちらの記事と こちらのチュートリアルなど 実際の実装方法は上記の記事の方が詳しいので、ここでは自分が担当したところでの実装で工夫していた点について主に記載していきます。 Apollo Clientを扱う GraphQLの準備 既存の記事や公式チュートリアルの記載内容が大変優れているので、詳細はそちらに譲ります。ここではシンプルに手順だけ。 Gemfile gem 'graphiql-rails' こちらのgemをインストールして $ bundle install $ rails g graphql:install のコマンドを実行したときに、routes.rbに以下の内容が記載されていると思います。 config/routes.rb Rails.application.routes.draw do post "/graphql", to: "graphql#execute" # 後略 end これによって、/graphqlのURLにPOSTでアクセスすることでGraphQLのメソッドが実行されます。 その後の方の定義などは前回の記事をご覧ください。 Apollo Clientの準備 apollo-clientをインストールし、 yarn add @apollo/client appolo-clientを初期化します。 App.jsx import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client"; // 解説します(★1) const client = new ApolloClient({ uri: 'http://localhost:3000/graphql', cache: new InMemoryCache() }); // 解説します(★2) export const App = () => { return ( <ApolloProvider client={client} > <Sample /> </ApolloProvider> ); } apollo-clientの初期化 まずはApolloClient()メソッドを用いてapollo-clientを初期化します。 以下の2つが必須オプションです。 App.jsx const client = new ApolloClient({ uri: 'http://localhost:3000/graphql', cache: new InMemoryCache() }); uri...apollo-clientがGraphQLの情報を受け取るところ。uriかlinkのどちらかが必須で、両方あった場合はlinkが優先される。 cache...apollo-clientがクエリの実行結果をローカルに保存するために使用するもの。@apollo/clientに同梱されているInMemoryCacheがおすすめ。 詳細なオプションはこちら。 このサンプルではApp.jsxにて初期化をしていますが、初期化の内容を他のファイルに記載してApp.jsxに読み込むこともできました。 ApolloProviderをアプリ上方に設置 そして、ApolloProviderをアプリの可能な限り上方に設置します。これに先ほど初期化したApolloClientのインスタンスを渡すことで下層のコンポーネントでapollo-clientが使えるようになります。 App.jsx export const App = () => { return ( <ApolloProvider client={client} > <Sample /> </ ApolloProvider> ); } クエリの実行 クエリを実行するにはuseQuery()メソッドを利用します。先程App.jsx内で呼び出した、Sample.jsx内で、このように記載します。 Sample.jsx import React from 'react'; import { useQuery, gql } from "@apollo/client"; const GET_USERS = gql` query GetUsers { users { id name email } } `; export const Sample = () => { const {loading, error, data} = useQuery(GET_USERS); // 解説します if (loading) return 'ロード中....'; if (error) return `Error ${error.message}`; return ( <> {data.users.map(user => ( <div key={user.id}> <h1>{user.name}</h1> <h2>{user.email}</h2> </div> )} </> ) }; useQueryメソッドはデフォルトで loading, error,dataの3つのプロパティを持つresultオブジェクトを返します。 それを分割代入でそれぞれ{loading, error, data}に代入しています。 loading...これがtrueである間、クエリはまだ実行中であり、結果はまだ返されていません。 error...クエリで1つ以上のエラーが発生した場合、このオブジェクトには、graphQLErrorsの配列または単一のnetworkErrorが含まれます。 result...GraphQLクエリの実行結果を含むオブジェクトです。 useQueryの詳細な仕様はこちら 完成! これで、ユーザーの情報を画面に描画することができたはずです。(既存のアプリは実像がかなり異なるので、抜け漏れがあるかもしれませんが、見つけ次第修正します) その他、 nestしたオブジェクトのGET ID等を利用した単一オブジェクトのGET mutationを利用したPOSTやUPDATEメソッドの実行 はまだできていませんが、徐々に試したいと思います。(試し次第追記します)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【コピペ】Railsで診断機能を実装する方法

今回はRuby on Railsで診断機能を実装します。 目次は以下の通りです。 1.コントローラー設計 2.データベース周り 3.Viewページ周り 4.ルート周り 1.コントローラー設計 perfumes_controller.rb class PerfumesController < ApplicationController def index end def new @perfume = Perfume.new end def show @perfume = Perfume.find_by(id: params[:id]) end def create @perfume = Perfume.new(perfume_params) params[:perfume][:question] ? @perfume.question = params[:perfume][:question].join("") : false if @perfume.save flash[:notice] = "診断が完了しました" redirect_to perfume_path(@perfume.id) else redirect_to :action => "new" end end private def perfume_params params.require(:perfume).permit(:id, question: []) end end 2.データベース周り ターミナル/コマンドプロンプト $ rails g model Perfume question:string ターミナル/コマンドプロンプト $ rails db:migrate 3.Viewページ周り perfumes/index.html.erb <!DOCTYPE html> <!-- この文章がHTML文章であることを伝える要素です。--> <html lang="ja"><!--言語の指定--> <head><!--ページに表示されない情報(サイトの裏側の設定)--> <meta charset="utf-8"> <title>香水診断スタート</title><!--ブラウザのタブのタイトルを指定--> </head> <body> <header> <h1 class="headline"> <a>Perfu_me</a> </h1> <ul class="nav-list"> <li class="nav-list-item">about fragrance</li> <li class="nav-list-item"><%= link_to "診断", perfumes_path, class: "link" %></li> </ul> </header> <div class="start"> <h6>Are you ready?</h6> <%= link_to "診断を始める", new_perfume_path, class: "link" %> </div> </body> perfumes/new.html.erb <%= form_for(@perfume, class: 'form-horizontal', role: 'form') do |f| %> <div class="container-sindan"> <div class="row"> <div class="col-12"> <p>Question1. どちらかと言うと…</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "1", nil %>じっくり考える方だ</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "2", nil %>考えるより行動する方だ</p> </div> <div class="col-12"> <p>Question2. 自分の価値観として近い方は…</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "1", nil %>周りの人と違う存在でありたい</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "2", nil %>周りと同じでいたい</p> </div> <div class="col-12"> <p>Question3. 人と接するときは…</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "1", nil %>相手の話をよく聞く方だ</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "2", nil %>自分の話をよくする方だ</p> </div> <div class="col-12"> <p>Question4. 大切にしたいのは…</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "1", nil %>論理性だ</p> </div> <div class="col-6"> <p><%= f.check_box :question, {multiple: true}, "2", nil %>情緒だ</p> </div> </div> </div> <div class="sindanbotan"> <%= f.submit "post" %> </div> <% end %> perfumes/show.html.erb <div class="intoro"> <h5>診断結果</h5> <p>あなたにおすすめの香りは…</p> </div> <div class="tweet-container"> <div class="tweet"> <% if @perfume.question == "1111" %> <h6>レモン</h6> <p>柑橘系の代表的な原料</p> <p>清涼感があり、爽やかな印象</p> <% elsif @perfume.question == "1112" %> <h6>シトラス</h6> <p>オレンジに似た柑橘系の果物</p> <p>リラックス効果がある</p> <% elsif @perfume.question == "1121" %> <h6>ローズ</h6> <p>華やかで上品な香り</p> <p>ストレスを緩和してくれる効果がある</p> <% elsif @perfume.question == "1122" %> <h6>ラベンダー</h6> <p>優しく女性らしい香り</p> <p>気持ちを落ち着かせてくれる</p> <% elsif @perfume.question == "1211" %> <h6>ジャスミン</h6> <p>爽やかなのに官能的な香り</p> <p>幸福感を得やすい</p> <% elsif @perfume.question == "1212" %> <h6>ピーチ</h6> <p>フレッシュで優しい香り</p> <p>アンチエイジングにも最適</p> <% elsif @perfume.question == "1221" %> <h6>アップル</h6> <p>特徴的で甘い香り</p> <p>万人受けしやすい</p> <% elsif @perfume.question == "1222" %> <h6>ユーカリ</h6> <p>しっかりとした優しい香り</p> <p>浄化作用があり。気持ちを落ち着かせてくれる</p> <% elsif @perfume.question == "2111" %> <h6>ローズマリー</h6> <p>きりりとした強めの香りが特徴的</p> <p>美容効果が高い</p> <% elsif @perfume.question == "2112" %> <h6>ベルガモット</h6> <p>柑橘系の果実</p> <p>甘くてフレッシュな、万能な香料</p> <% elsif @perfume.question == "2121" %> <h6>ムスク</h6> <p>雄のジャコウジカの腹部にある香嚢から抽出した香料</p> <p>官能的で重い香り</p> <% elsif @perfume.question == "2122" %> <h6>アンバー</h6> <p>マッコウクジラの結石から抽出した香料</p> <p>魅惑的で色気のある香り</p> <% elsif @perfume.question == "2211" %> <h6>シナモン</h6> <p>甘いスパイスの香り</p> <p>香水のアクセントとしてよく使われる</p> <% elsif @perfume.question == "2212" %> <h6>バニラ</h6> <p>甘くて官能的な香り</p> <p>上品で年齢を問わず人気が高い</p> <% elsif @perfume.question == "2221" %> <h6>イランイラン</h6> <p>色気のある濃厚で甘い香り</p> <p>恋愛に効果があり</p> <% elsif @perfume.question == "2222" %> <h6>サンダルウッド</h6> <p>お香としてよく使われる白檀の香り</p> <p>集中力を高める効果もあり</p> <% end %> </div> 4.ルート周り routes.rb #省略 resources :perfumes #省略 以上です!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Devise】本番環境でログインできないときの解決方法

はじめに deviseを使用したログインを本番環境で行ったが、再度ログイン画面へリダイレクトされてしまった。 結論、nginxの設定がうまくいっていなかったため、以下のように解決方法をまとめた。 環境 rails 6.1.4 ruby 2.7.3 nginx 1.20.1 puma 4.3.8 devise 4.8.0 解決方法 ①nginx設定ファイルに「proxy_set_header X-Forwarded-Proto $scheme;」を追加 #/etc/nginx/conf.d/hoge.com.conf upstream puma-production { server unix:/var/www/html/<app名>/shared/tmp/sockets/puma.sock; } server { listen 80; server_name <ドメイン>; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name <ドメイン>; ssl_certificate /etc/letsencrypt/live/<ドメイン>/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/<ドメイン>/privkey.pem; root /var/www/html/<app名>/current/public; location / { try_files $uri @app; } location @app { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; <---追記 proxy_pass http://puma-production; } } ②nginxを再起動 $ sudo systemctl restart nginx まとめ リバースプロキシを使用していたため、nginxの設定に追記が必要だった。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

herokuでFailed to install gems via Bundlerが出てデプロイできなかった理由

はじめに 私は初学者です。この記事も、かなり根本的なミスについてです。 同じく初学者でherokuのデプロイがうまくいかない方の少しでも役に立てればと思い、恥を忍んで投稿します。 それと、考えもしなかった凡ミス、想像もしてなかった原因で、衝撃だったという理由もあります、、、 用語の使い方等おかしな点もあると思いますが、ご指摘いただければと思います。 結論 結論を言うと、 全ての原因はenvironment直下で git init をし、ワークスペース全体をgitのリポジトリ管理下に置いていたことでした。 /environment $git init  /environment(main) $ environmentに(main)とついていることや、 gitでリポジトリを開いてワークスペース全体が登録されていることに違和感を覚えていませんでした、、、 故に、いくらプロジェクトフォルダに移動して、その中のGemfile、Gemfile.lockを編集、bundle install、gitにadd、commitしてもデプロイが成功しなかったわけです。 herokuが参照していたのは、environmentディレクトリ直下にあるファイルたち(appフォルダやGemfile、Gemfile.lockも)だったため、私がデプロイしたいプロジェクトフォルダの中を動かしても、関係なかった。 隠しフォルダを表示させると、environment直下に.gitフォルダがありました。(=ワークスペース全体をgit管理下に置いている) なので、 /environment/ $rm -rf .git を実行し、ワークスペース全体を一旦gitのリポジトリ管理下から外し、 ちゃんとプロジェクトフォルダに移動して、git init等で新たにgitに登録しなおし、一連の流れでデプロイ成功しました。 最後に つたない説明&なかなかないミスで、よくわからない記事になってしまったかもです。 とにかく、git initするときは、ちゃんとプロジェクトフォルダへ移動してからにしましょう。 なんとなくで進んでいると、後々躓きます。 デプロイできずにネットで検索しまくっていましたが、デプロイできないという質問が結構ありました。 こちらのサイト等でも未解決が結構あったので、こういうこともあるのか、、、とgitのディレクトリを見返していただけたらと思います。大丈夫だとは思いますが、、、 私が今よりも初学者だったころにgit initしたので、間違えに気づかず、正直時を経て当時の事もよく覚えてないです(笑)。 根本的なところを間違えていた場合、なかなか解決法がネットで出てこないことがあります。今回がそれだったので記事にしました。 解決してよかった、、、
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

自分以外のユーザーページにアクセスさせない設定

この記事で学ぶ事 URL http://localhost:3000/users/1 この最後の1を2という風に直接入力すると他のユーザーページに遷移できる 今回は ①アクセスさせない ②存在しないユーザーの場合、ActiveRecord::RecordNotFound例外ではなくてnilを返す 設定をしていきます。 ①アクセスさせない app/controller/application_controller def user_check return if User.find(params[:id]) == current_user # もし入力した数値のidユーザーとログイン中のユーザが一緒ならこのメソッドを抜ける flash[:alert] = '警告:禁止行為' redirect_to user_path(current_user) end app/controller/users_controller before_action :user_check これで自分のページへリダイレクトされフラッシュメッセージが表示されます。 ②存在しないユーザーの場合、ActiveRecord::RecordNotFound例外ではなくてnilを返す findを使用して存在しないユーザーidの場合、このような事になります。 利用者が例外な事をしようとしているから別にこれでも良いのかなと思いつつ例外を表示させない方法を調査・・・ findをfind_by_idを使用する事でnilが返ってくるので可能な事が分かりました! def user_check return if User.find_by_id(params[:id]) == current_user flash[:alert] = '警告:禁止行為' redirect_to user_path(current_user) end これで例外ではなく、自分のページへリダイレクトされます。 考え方や記述内容がおかしいなど、何かお気づきの点がありましたらご指摘くださると幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails コンテナの docker build を高速化してみる

BuildKit を有効にして docker build した場合、どのくらい高速になるのか確認しました。 BuildKit 詳細まで理解していませんが、ざっくりまとめると、 依存関係のない命令を並列実行できる コンパイラやパッケージマネージャのキャッシュディレクトリを保持できる これらの仕組みにより、ビルドを高速化しているようです。 利用方法 BuildKit は docker v18.06 から使えます。 環境変数 DOCKER_BUILDKIT=1 を設定するだけで有効になります。 BuildKit 無効のとき BuildKit を無効化。 $ export DOCKER_BUILDKIT=0 中間レイヤ削除とキャッシュ不使用のオプションを付けてビルド。 $ docker build . --rm --no-cache -t rails_app -f dockerfiles/rails/Dockerfile ビルド時間は 4m27s でした。 BuildKit 有効のとき 次は有効にしてビルドしてみます。 $ export DOCKER_BUILDKIT=1 $ docker build . --rm --no-cache -t rails_app -f dockerfiles/rails/Dockerfile ビルド時間は 2m54s でした。 約35%のビルド時間削減になりました!(もちろん環境やイメージの内容にも依りますが) ビルド時間の短縮以外で嬉しかったこと ビルド中の画面出力が見やすくなっていました。 従来のビルドでは膨大な長さになる上に内容も分かりにくかったです。 BuildKit では、ステータスがレイヤ毎にまとめられています。 また、並列に処理が進んでいることが見て分かるようになってます。 まとめ BuildKit を有効にしてビルド時間が短縮できることが確認できました。 BuildKit にはこの他にも機密情報をコンテナに渡すためのオプションや、SSH エージェントによる接続を許可するオプションなどが追加されているようです。またの機会に試してみたいと思います。 ちなみに、ビルドした Dockerfile はこちらです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rails s で An error occurred while installing pg (1.2.3), and Bundler cannot continue.が出た

概要 macを買い替え、以前のPCで技術書を参考に自作したアプリケーションを立ち上げようとrails s をしたら、表題のエラーが出た。 開発環境 MacBook Pro (13-inch, M1, 2020) macOS Big Sur バージョン 11.5.2 rails sでエラーが出た terminal $ rails s ~ An error occurred while installing pg (1.2.3), and Bundler cannot continue. Make sure that `gem install pg -v '1.2.3' --source 'https://rubygems.org/'` succeeds before bundling. 素直にやってみる。 terminal $ gem install pg -v '1.2.3' terminal $ rails s Ignoring bootsnap-1.7.3 because its extensions are not built. Try: gem pristine bootsnap --version 1.7.3 Ignoring bootsnap-1.7.1 because its extensions are not built. Try: gem pristine bootsnap --version 1.7.1 Ignoring bootsnap-1.5.1 because its extensions are not built. Try: gem pristine bootsnap --version 1.5.1 Ignoring eventmachine-1.0.9.1 because its extensions are not built. Try: gem pristine eventmachine --version 1.0.9.1 Ignoring ffi-1.14.1 because its extensions are not built. Try: gem pristine ffi --version 1.14.1 Ignoring ffi-1.13.1 because its extensions are not built. Try: gem pristine ffi --version 1.13.1 Ignoring ffi-1.12.2 because its extensions are not built. Try: gem pristine ffi --version 1.12.2 Ignoring msgpack-1.3.3 because its extensions are not built. Try: gem pristine msgpack --version 1.3.3 Ignoring nio4r-2.5.5 because its extensions are not built. Try: gem pristine nio4r --version 2.5.5 Ignoring nio4r-2.5.4 because its extensions are not built. Try: gem pristine nio4r --version 2.5.4 Ignoring sqlite3-1.4.0 because its extensions are not built. Try: gem pristine sqlite3 --version 1.4.0 Ignoring thin-1.8.0 because its extensions are not built. Try: gem pristine thin --version 1.8.0 Ignoring thin-1.5.1 because its extensions are not built. Try: gem pristine thin --version 1.5.1 => Booting Puma => Rails 5.2.4.5 application starting in development => Run `rails server -h` for more startup options Puma starting in single mode... * Version 3.12.6 (ruby 2.6.6-p146), codename: Llamas in Pajamas * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://localhost:3000 Use Ctrl-C to stop 一応サーバーは立ち上がったが、Ignoringが気になるので消したい。 $ gem install bundler $ bundle install で消えました。 参考 https://tsubasa0105.hatenablog.com/entry/2018/11/29/180051 https://qiita.com/ROY_M/items/43fd1370e3d89ae50074 https://teratail.com/questions/139925
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MinitestのテストをRSpecに書き換えた

現在ポートフォリオ作成中 minitestで書いたテストを途中からRspecに変更したので記録します テストに関してはまだまだ初学者のため理解の浅い部分が多々あると思います。誤り等ありましたらご指摘頂けますと大変ありがたいです ※理解が深まったらどんどん追加・修正していきます やったこと ・RSpecインストール ・RSpecテストファイル作成 ・minitest見ながらRSpec書く ・実際にテストする ・testディレクトリ削除 ・必要(かもしれない)ファイルをrspecディレクトリ直下に移動  RSpecのインストール 公式ドキュメント(Github)がわかりやすい 移行手順 どのspec使うか調べる 書き換える テストしてみる どのspec使うか ・書き換えたいテストの継承元のクラスを見る ※static_pages_controller_test.rbならActionDispatch::IntegrationTestが当てはまる ・公式ドキュメントの表見る ※公式ドキュメントのこの表に、どのクラスはどのスペックを使えばいいのか書いてあるので参照 Spec type Corresponding Rails test class model controller ActionController::TestCase 略 request ActionDispatch::IntegrationTest 略 上の例だとActionDispatch::IntegrationTestなのでrequest specを使用(spec/requests/static_pages_spec.rb) ※コントローラーのテストなのでcontroller specかと思ったが、requestの方を使用します static_pages_spec.rbを開いて、minitestのものを書き換えていく まず書き換え元(minitest) require 'test_helper' class StaticPagesControllerTest < ActionDispatch::IntegrationTest def setup @base_title = "App name" end test "should get home" do get root_path assert_response :success assert_select "title", "App name" end test "should get about" do get about_path assert_response :success assert_select "title", "About | App name" end end Rspecで書き換えたものがこちら require 'rails_helper' RSpec.describe "StaticPages", type: :request do let(:base_title) {'App name'} describe "GET /home" do it "should get home" do get root_path expect(response).to have_http_status(200) expect(response.body).to match(/<title>ホーム \/ #{base_title}<\/title>/i) end end describe "GET /about" do it "should get about" do get about_path expect(response).to have_http_status(200) expect(response.body).to match(/<title>アプリ詳細 \/ #{base_title}<\/title>/i) end end end assert_response :successはexpect(response).to have_http_status(200)と書き変わっているが、200ならリクエストは正しく処理されたという意味になります 参考:HTTPステータスコードとは?種類とそれぞれの役割について これでテストは書き換えられたので実行してみる このファイルだけ実行したいので以下のコマンド実行 bundle exec rspec spec/requests/static_pages_spec.rb % bundle exec rspec spec/requests/static_pages_spec.rb ... Finished in 0.0664 seconds (files took 1.34 seconds to load) 3 examples, 0 failures 無事テスト通った でも何がうまくいったか見えた方がいいので以下のように-f documentation追加して実行した bundle exec rspec spec/requests/static_pages_spec.rb -f documentation % bundle exec rspec spec/requests/static_pages_spec.rb -f documentation ... StaticPages GET /home should get home GET /about should get about Finished in 0.0801 seconds (files took 1.65 seconds to load) 3 examples, 0 failures itやdescribe内のテキストが表示されわかりやすくなった 参考:RSpecの実行結果をドキュメント形式で channels/application_cable_connection_test.rbはコメントのみだったので移行せず削除 application_system_test_case.rbはアプリ作成した時にテストのディレクトリに作られる→なのでRspecディレクトリにそのまま移動させた 参考:Rails テスティングガイド 全てのテストで書き換えたらtestディレクトリを削除(Rspec使うならもう必要ないので) これで行けると思うがもしminitestでテストされてしまったらその時対処してまた記事修正します まとめ 正直全然理解できていない・記事もまとまっていないが、今後テスト書いていく上で深まっていくと思うので先に進みます 調べて正しいと思うことをやっていますが、間違いなどありましたらコメントいただけると大変ありがたいです。。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

wicked_pdf 本番環境で動かない問題

起きたこと wicked_pdfをEC2にデプロイしたところ表示されず‥ ログを見ると以下エラー ActionView::Template::Error (The asset "number_pages.js" is not present in the asset pipeline. 対処法 以下の部分を削除 <!doctype html> <html> <head> <meta charset='utf-8' /> <%= wicked_pdf_stylesheet_link_tag "pdf" -%> #--------------削除------------------------------------- <%= wicked_pdf_javascript_include_tag "number_pages" %> #---------------------------------------------------------- </head> <body onload='number_pages'> <div id="header"> #--------------削除-------------------------------- <%= wicked_pdf_image_tag 'mysite.jpg' %> #------------------------------------------------- </div> <div id="content"> <%= yield %> </div> </body> </html> 原因 公式のこの部分 <!doctype html> <html> <head> <meta charset='utf-8' /> <%= wicked_pdf_stylesheet_link_tag "pdf" -%> <%= wicked_pdf_javascript_include_tag "number_pages" %> </head> <body onload='number_pages'> <div id="header"> <%= wicked_pdf_image_tag 'mysite.jpg' %> </div> <div id="content"> <%= yield %> </div> </body> </html> をそのまま持ってきてたのでwicked_pdf_javascript_include_tag "number_pages"の部分は今回は使ってなかったからエラーが起きたのだと思われ 現にwicked_pdf_javascript_include_tag "number_pages"の部分を削除したら今度は 以下のエラーが出たのでここも今回は不要ってことでこれも削除 ActionView::Template::Error (The asset "mysite.jpg" is not present in the asset pipeline. その後 その後無事PDF出力はしたが今度は英語と数字部分は出力されるが日本語部分が出力されず‥ 対処法 Linuxには日本語が入っていないらしいので 以下をcurrent内でインストール $ yum install -y ipa-gothic-fonts $ yum install -y ipa-mincho-fonts これで無事表示された! 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

delegateについて

こんにちは、プレイライフの熊崎です! 昨日の夜食べたラーメンのせいで、若干胃もたれ気味です。 学生の頃はラーメン+ライスでも全然平気だったのに、、、 時の流れを感じますね笑 そんな僕の話は置いておいて、delegateについての記事を書いていきたいと思います。 deledateとは delegateマクロを使って、メソッドを簡単に委譲できます。 https://railsguides.jp/active_support_core_extensions.html?version=6.0#delegate → あるクラスに存在するメソッドを他のクラスで使用できるようにする どんな時に使用するか? 関連付けられているモデルのメソッドを直接使用したいとき。 基本の使い方 sample.rb class SampleUser < ApplicationRecord has_one :sample_plan     # delegateには複数のメソッドを指定できる。 delegate :free_plan?, to: :sample_plan end # SamplePlanモデルはname属性を持っていると仮定 # 有料プランはnameが”有料プラン” # 無料プランはnameが”無料プラン” class SamplePlan < ApplicationRecord belongs_to :sample_user def free_plan? name == "無料プラン" end end # ユーザーが無料プランかどうかを確認したい時 # delegateを使わないとこんな感じ。冗長だしパッと見で意味がわかりづらい。 sample_user.sample_plan.free_plan? # delegateを使用することで、SamplePlanモデルのメソッドを直接実行できる。簡潔だし、意味も明快 sample_user.free_plan? オプション :allow_nil 上記の例で、あるsample_userに、sample_planが紐づいていない場合sample_user.free_plan?を呼び出すとNoMethodErrorを返す。 allow_nil: trueにすることで、nilを返すようにできる。 :prefix メソッド名を変更したいときに使用する。 sample.rb class SampleUser < ApplicationRecord has_one :sample_plan delegate :free?, to: :sample_plan, prefix: :plan end # SamplePlanモデルはname属性を持っていると仮定 # 有料プランはnameが”有料プラン” # 無料プランはnameが”無料プラン” class SamplePlan < ApplicationRecord belongs_to :sample_user def free? name == "無料プラン" end end # ユーザーが無料プランかどうかを確認したい時 sample_user.sample_plan.free? # prefix: :planとしたことで、free?メソッドの名前がplan_free?に変更された。 sample_user.plan_free? まとめ delegateを使用することで、関連するモデルのメソッドを直接参照できる。 delegateを使用することで、より可読性の高いコードを書くことができる。 参考URL https://railsguides.jp/active_support_core_extensions.html?version=6.0#delegate https://api.rubyonrails.org/classes/Module.html#method-i-delegate
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】 環境構築

手順 ① 作業ディレクトリの作成 $ mkdir workspace/my/rails_sample $ my/rails_sample ② rubyのバージョン切り替え $ rbenv install 2.7.2 $ rbenv local 2.7.2 $ ruby -v # 指定バーションが表示されて売ればOK rbenv 〜 rubyのバージョンを切り替えるためのツール ③ bundleとrails $ gem install bundler # rubyのライブラリを管理するbundlerをrubyにインストール $ bundle init # 生成されたGemfileをgem "rails"に編集 $ bundle install bundle init 〜 現在の作業ディレクトリ内に、Gemfileを生成 ④ プロジェクトの作成 rails _6.0.3.7_ new sample その他 nodeやyarnのインストール データベースの作成 フロントエンドの構築 ext...
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Railsを使用する恩恵

おはようございます、プレイライフの熊崎です。 今週は雨の日が多かったですね。 来週も雨の日が多いようで、気が滅入ってしまいます。。。 来週も、雨にも負けず風にも負けず仕事を頑張っていきたいと思います! なぜこの記事を書こうと思ったか? 業務を行っていて、railsの機能を充分には使いこなせていなかった。(今振り返ると、そもそも使いこなそうともしていなかったように感じる。) 原因を考えてみたら、下記の原因が考えられた。 なんでrailsの規約に沿った書き方をしなければいけないのか?という理由が自分の中で明確になっていなかった。 スピード感を持って開発することが求められている中で、とりあえず動くものを作るということに意識を向け過ぎた。 スピード感を持って開発することが求められている中で、とりあえず動くものを作るということに意識を向け過ぎた。に関しては、今までの経験上、後で修正しようと考えても絶対修正まで手が回らないので、都度railsの機能を利用することを徹底することにした。 ↑ のように考えても、railsを使用する恩恵の理解が薄いと絶対に上記の意識も薄れてくるので、アウトプットを行うことで自身の理解を深めようと思ったため。 本記事の対象者 ということで、本記事は以下のような方々を対象とする。 自分と同じように何となくでrailsを使用していた方 railsの基本理念 Convention over Configuration(設定より規約) アプリケーションの実装を行う上で、決めなくてはいけないことは沢山ある。(ex:主キーの名前をどうするか、など) そのような決めなくてはいけないこと(設定)を規約に移すことで、設定を決定する時間を軽減することをモットーとする。 railsを使用するメリット 上記の基本理念に則って作られているため、規約に則った書き方をすれば、作業時間を短縮できる。 初心者でも、規約に則った書き方をすれば、最低限のコードの質は担保される。(もちろん、命名規則や単一責任の原則など、コードの質を担保するためには他にも考慮しなければならないことが沢山ある。) 単純にコード量が少なくて済む。 可読性が上がる。 メリットの補足(コード量が少なくて済む・可読性が上がる について) 例: 性別が男性のUserを探したい場合 sample.rb # すでにSampleUsersテーブルに男性や女性の情報が登録されていると仮定する。 # railsのActiveRecordを利用した場合 SampleUser.where(sex: :man) # ↑をrubyで似たようなことを行う場合 SampleUser.select { |user| user.sex == "man" } 前者の方が記述量が少ない。(検索条件が複雑になればさらに記述量に差が出てくる。) また、whereは検索用のメソッドなので、whereと書いてあれば、「何か条件を設定していて、その条件に当てはまるレコードを検索している」ということが直感的に理解しやすい。 一方で、後者だと記述量が多い上に、パッと見で何をやっているか少しわかりづらい。(このコードは短いので、わからなくはないが、検索条件が膨らんでくるとさらに読みづらくなることが予想される。) まとめ railsの理念はConvention over Configurationである。 railsを使いこなすことで、rubyで実装するより、記述量が少なく、かつわかりやすいコードを書ける。 最後に そもそもフレームワークは楽をするために、先人達が知恵を絞って作ったものだから、フレームワークを積極的に使用して作業効率を上げるのは当たり前のことだと思う。 しかし、とにかく動くものを作るという目先のことに囚われすぎて、フレームワークを積極的に使用することに意識が向いていなかった。 とにかく動くものを作る → フレームワークを使わない → フレームワークの使い方を覚えない → 作業スピードが上がらない といった負のスパイラルに陥るため、今後は使ったことのないrailsの機能でも積極的に使っていきたいと思う。 参考文献 https://rubyonrails.org/doctrine
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

searchアクション

1.ルーティング設定をする(app - config - routes.rb)      collection do       get 'search'      end 2.コントローラーに「searchアクション」を定義する( app - controllers - places_controller.rb) def search @places = Place.search(params[:keyword]) end 3.モデルに、self.search(search)を設定する(app -models -place.rb)  def self.search(search)   if search != ""   Place.where('name LIKE(?)', "%#{search}%")  else   Place.all  end end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【mariaDB】データベースの中身の確認について

環境 Ruby on rails 6.1.4 ruby 2.6.5 capistrano mariaDB 5.5.68 経緯 AWSのEC2を使った環境構築をしています。 capistranoを使い自動デプロイを完了しています。 ローカル環境ではSequel Proを使っていたので、ローカルで保存した情報はすぐ確認することができました。 しかし、本番環境のデータベースの中身を確認する方法がわからず。 素人丸出しの「mariaDB 中身 確認」だとかで検索しましたが出てくるのは「select * from モデル名で中身見れますよ〜」ばかりでした。(初心者すぎて調べ方が分かっていない) そもそもDBにたどり着く方法がわからず悩んでいたのですが、なんとか辿り着けたので備忘録を兼ねて記事に残そうと思います。 コード ターミナル内 まずEC2へログインします #ホームディレクトリに移動 xxxx@yyyynoAir ~ % cd #sshディレクトリに移動 xxxx@yyyynoAir ~ % cd .ssh/ #EC2へログイン(ssh -i ダウンロードした鍵の名前.pem ec2-user@作成したEC2インスタンスに紐付けたElastic IP) xxxx@yyyynoAir .ssh % ssh -i 0000xxxx.pem ec2-user@12.345.67.890 #ログインできればEC2のロゴ?が出現します __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| ログイン後 #currentディレクトリに移動 [ec2-user@ip-123-45-67-8 ~]$cd /var/www/アプリケーション名/current #mysqlへアクセスするコマンドを入力 [ec2-user@ip-123-45-67-8 current]mysql -u root -p アプリケーション名_production #パスワードを求められるので入力(見た目上は何も表示されませんが入力されているので完了後enterを押す) Enter password: #DBの中に入っているので、select文を使って検索する MariaDB [アプリケーション名_production]> select * from stores \G; 流れとしては上記の通りです。 mysqlのパスワードがわからない方はEC2内のホームディレクトリ[ec2-user@ip-123-45-67-8 ~]へ戻ってもらい「env」と入力すればパスワードが確認できるはずです。 また、select文の\Gはターミナル上で表示されるデータが見やすくなる(抽象的ですいません)ので使っています。 以上です。 ローカルでのデータはすぐ目視で確認できていたので、いざ本番環境のデータを見るとなったときに「どこ見に行けばいいの?」と思ったので作成しました。 内容に不備がございましたらご指摘いただけますと幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[メモ] Docker「ruby:3.0-slim-buster」に Rails6 (簡素版) を導入してみる (Django使用経験あり)

概要 「Ruby経験あり、Rails 経験なし、JavaScript アプリ開発経験なし」の観点で、 御著書 『Railsの教科書』 で Rails6 の学習をしてみたときの記録である. このとき、Dockerイメージ「ruby:3.0-slim-buster」に対して Rails6 を導入してみたので、 書き残しておく. また、Django を用いたバックエンド開発経験はあるので、その視点でメモも 書いてみた. なお、ここでの "簡素版" とは「Nginx や PostgreSQL や Unicorn などは導入しない」1 という意味である.   手順のみ 実行時の UID は root である. なお、「ruby:3.0-slim-buster」 は Debian 10 なので、Ubuntu 18.04 にも転用できるはずである. 基本的には次の公式ドキュメントの手順を実施するのだが、少し補足してみた. ・https://guides.rubyonrails.org/getting_started.html #!/bin/bash apt update -y apt install -y autoconf bison build-essential libssl1.1 libyaml-dev \ libreadline-dev zlib1g-dev libncurses5-dev libffi-dev \ libgdbm-dev sqlite3 libsqlite3-dev apt install -y curl curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash cat <<'EOL' | tee -a > $HOME/.bashrc export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion EOL . $HOME/.bashrc nvm install --lts npm install -g yarn gem install rails 手順 + 個人的メモあり #!/bin/bash apt update -y # 推測混じりになるが、SQLite3 インストールに加えて、DB操作 (SQLクエリ発行やマイグレーション) や、 # SSL通信に必要なパッケージをインストールしているのだろう. apt install -y autoconf bison build-essential libssl1.1 libyaml-dev \ libreadline-dev zlib1g-dev libncurses5-dev libffi-dev \ libgdbm-dev sqlite3 libsqlite3-dev apt install -y curl # NVM のインストールをする. 後段の Node.js と npm をインストールするため. (後述の「補足」を参照) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash # NVM を使うための設定を $HOME/.bashrc に追記する. cat <<'EOL' | tee -a > $HOME/.bashrc export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion EOL # NVM を使うための設定を有効にする . $HOME/.bashrc # Node.js をインストールすると、同時に npm もインストールされる. (後述の「補足」を参照) nvm install --lts # npm を使って Yarn をインストールする (yarn -v でバージョン表示されればOK) npm install -g yarn # rails をインストールする (Django における pip install Django に相当する) # rails -v でバージョン表示されればOK gem install rails 補足 項目 URL npm, nvm, Node.js のメモ https://qiita.com/robozushi10/items/f8e1e2cae94f87b98acc npm, nvm, yarn のメモ https://qiita.com/robozushi10/items/fabbd40e560557c7394e 参考にした情報 書籍 書籍 URL 『Railsの教科書』 https://railstutorial.jp/textbook 記事 URL https://qiita.com/ashketcham/items/48d64e960d436f8b6f78 https://qiita.com/pharma_tech3/items/2ab578eb5b07ff0ca296 https://qiita.com/GalaxyNeko/items/630ac869d3bbbe93034b https://qiita.com/masatwork/items/1b5d190cc76f5eeffbb7 以上 Rails 詳細は不明だが、Django でも Nginx, PostgreSQL, Gunicorn の組み合せがあるので、推測可能である ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring Boot学習者が他言語のWebフレームワークを触ってみて気づいたこと

こんにちは。ワタナベトシヒロです。 私はJavaのWebアプリケーションフレームワークであるSpring Bootを学習してきましたが、今回は他の言語のフレームワークも触ってみました。 Spring Boot(Java)、Laravel(PHP)、Ruby on Rails、Django(Python)を比較して、気づいたことを挙げていきます。 ただし、Spring Boot以外のフレームワークでは簡単なCRUD処理のAPIを実装しただけなので、フレームワークへの深い理解はできていません。 Spring Bootの特徴 コマンドを入力する機会が少ない? Spring Bootのプロジェクト作成はWeb上で行ったり、IDEのGUI上で行うことが多いです。 また、LaravelやRailsではモデル作成やコントローラー作成用のコマンドがありますが、Spring Bootではコマンドを使ってファイルを作成する例は見たことがありません。 Spring Bootでは他のフレームワークと比べてCLIを操作する機会が少ない気がします。 DBのテーブルの作成はSQLで行う Laravel、Rails、Djangoにはマイグレーションという機能があり、SQLを書かなくてもDBのテーブルを作成できますが、Spring Bootではフレームワークの機能を使わずにSQLでテーブルを作成しておくのが一般的だと思います。 プロジェクト作成時に生成されるコード量が少ない 最初に作成されるjavaファイルは3つだけで、最低限の記述しかありません。 htmlファイルも用意されておらず、初期状態でアプリを起動してアクセスしても何も表示されないのはSpring Bootだけです。 ただし、ディレクトリの階層は深く、初期設定では無駄なディレクトリ構成に感じてしまいます。 Spring Bootはパッケージ数が多い大規模なアプリのために設計されているのかもしれません。 Laravel プロジェクト作成時に生成されるファイル数が多い Laravelはプロジェクト作成時点でファイル数が多く、ディレクトリ構成もしっかり決められています。 ↑ Spring Boot、Laravel、Rails、Djangoの4つの新規プロジェクトをまとめたGitリポジトリのコード割合です。BladeはLaravelのテンプレートエンジンなので、約7割がLaravel関連のコードで占められていることになります。 Ruby on Rails Windowsでの開発が難しい WindowsでRailsの開発をしようとすると、エラーに遭遇することが多く、特に環境構築で苦戦しました。 WindowsのWSL2という機能を使い、Linuxの仮想環境で環境構築をしてみましたが、それでもスムーズにいきませんでした。 (謎の警告が出たり、Rubyのインストール時に1時間以上インストール中と表示され続ける問題がありました) Django 同名のフォルダやファイルが多くなりがち? django-admin startproject <アプリ名>でDjangoプロジェクトを作成すると、<アプリ名>のフォルダが作成され、その中に同名の<アプリ名>のフォルダが作成されます。 また、__init__.pyやurls.pyなど、同名のファイルが複数作られることが多いですが、このように同名のフォルダやファイルが多いと紛らわしいのでは?と思いました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails chart.js

chart.jsとは Railsでグラフ化するためのライブラリです。 Jsとはjavascriptのことです。 グラフと連動することで中の情報を見やすくすることができます。 chart.js導入 まず導入法についてです。 gem 'chart-js-rails', '~> 0.1.4' #追記 その後 $ bundle install その後コントローラー作成 $ rails g controller chart index ルーティングに追記 routes.rb Rails.application.routes.draw do root 'chart#index' end package.jsonに追記 package.json { "name": "chart_js_sample", "private": true, "dependencies": { "chart.js": "^2.7.1" ←★追記 } } $ yarn install で読み込み ⚫︎グラフの読み込み https://www.chartjs.org/docs/latest/ の内容を読み込み 注意 今回の記事では実装をしていないので 未完成の部分があります。 実装される場合は下の資料が詳しく載っているので そちらからお願いします。 あくまで初学者用の記事です。 ⚫︎公式サイト https://www.chartjs.org/ ⚫︎参考引用資料 https://qiita.com/Y_uuu/items/ef107a02c27836696545 https://qiita.com/4EAE_Learner/items/d3a97f1115f5658b4e47
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】複数モデルの作成日付一覧を重複なく表示する

ポートフォリオ作成中の学びのアウトプットとして投稿させて頂きます。 勉強用アプリを作成中に実装した保存された回答(複数モデル存在)を日付順に重複なく表示する方法です。 実現したいこと users_controllerのshowアクションで回答の作成日付一覧をviewに表示してそれぞれの日付をクリックするとその日に作成された回答一覧を確認できるようにしたい。 ※下図のイメージ モデル 回答用モデルとして「answer」と「reaction」が存在。 showアクションとviewの中身 users_controller.rb def show @answers_dates = current_user.answers.map{|dates| dates.created_at.to_date} @reactions_dates = current_user.reactions.map{|dates| dates.created_at.to_date} @dates = @answers_dates.push(@reactions_dates).flatten.uniq.sort.reverse end show.html.erb <% @dates.each do |record| %> <li> <%= link_to record, answers_path(created_at: record) %>    </li> <% end %> 中身の説明 @answers_dates = current_user.answers.map{|dates| dates.created_at.to_date} @reactions_dates = current_user.reactions.map{|dates| dates.created_at.to_date} 全てのanswer及びreactionをインスタンス変数に配列として保存する。同時に年月日だけ表示されれば良いのでto_dateメソッドを用いて変換。 @dates = @answers_dates.push(@reactions_dates).flatten.uniq.sort.reverse 二つの配列をpushメソッドで結合。結合すると配列が入れ子構造になるので(ex,[2021-09-08, [2021-09-08,2021-09-09]])、flattenメソッドで入れ子構造を外す。uniqメソッドで重複を除去、さらにsort.reverseで日付が近い順に並び替える。 ※入れ子構造を外さないとuniqで上記の例だと2021-09-08の重複を除去できない。 <% @dates.each do |record| %> <li> <%= link_to record, answers_path(created_at: record) %>    </li> <% end %> 後は表示される日付にリンクを付属し、その日付をparamsとしてパスに与えることでその日付に作成されたモデルを取り出せる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む