20210418のRubyに関する記事は11件です。

【Ruby】eachとmapの違い

eachメソッド def each_sample (1..10).to_a.each do |i| i + 10 end end => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 【特徴】 配列の要素の数だけブロックを繰り返し実行する。 繰り返しごとにブロック引数には各要素が順に入る。 戻り値はレシーバ自身 mapメソッド def map_sample (1..10).map do |i| i + 10 end end => [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 【特徴】 要素の数だけ繰り返しブロックを実行する。 戻り値はブロックの戻り値を集めた配列。 以上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[即席]Railsの複数画像投稿に枚数制限をつけたい!

はじめに 本日、ポートフォリオ作成中に、「あ、複数画像投稿の枚数の制限をかけたいな〜」と思い調べたのですが、あまり「これだ!」と思える記事に出会えなかったので、私なりに簡単に楽に実装できる方法を考えてみたのでここでアウトプットします。もしかしすると、かなり脆弱性のある実装かもしれませんが、そこは個々のご判断でお願いいたします。 結論 結論からいうと、添付したファイル数が基準を超えたときに、アラートを出して投稿(更新)ボタンを非活性化してしまうということです。 以下に具体的なコードを貼っておきます. 実言うと、これはプレビュー機能実装で使ったコードなんですけどね、、、 preview.js document.addEventListener('DOMContentLoaded', function(){ const ImageList = document.getElementById('practice-views'); const submit=document.getElementById("submit"); //更新ボタンの取得 //ファイル選択をしたときに以下を発火 document.getElementById('practice_image').addEventListener('change', (e)=>{  while(ImageList.lastChild){ ImageList.removeChild(ImageList.lastChild);//ここは気にしなくてOKです } }); document.getElementById('practice_image').addEventListener('change', (e)=>{ const files = e.target.files;   //以下で枚数制限をかけています。 if(files.length>4){ alert("投稿できる画像数は4枚までです"); submit.setAttribute("disabled",true); //非活性にする!!!! return false; }else{ submit.setAttribute("disabled",false);//活性にする!!!! } Array.from(files).forEach(file => { const blob = window.URL.createObjectURL(file); const imageElement = document.createElement('div'); imageElement.setAttribute('class','preview_image' ); // 表示する画像を生成 const blobImage = document.createElement('img'); blobImage.setAttribute('src', blob); imageElement.appendChild(blobImage); ImageList.appendChild(imageElement); }); }); }); とりあえず、結論だ見たい方はここに着目してください。 preview.js document.getElementById('practice_image').addEventListener('change', (e)=>{ const files = e.target.files;   //以下で枚数制限をかけています。 if(files.length>4){ alert("投稿できる画像数は4枚までです"); submit.setAttribute("disabled",true); //非活性にする!!!! return false; }else{ submit.setAttribute("disabled",false);//活性にする!!!! } イベントオブジェクトの中から、添付したファイルの情報をとってきてfilesに格納しています。そして、そのfiles.lengthで格納されているデータの数を見ているわけです。たったこれだけです。!!! ちなみにeturn false;にしているのは、画像枚数が制限つを超えた場合は後の処理をさせたくないからです。 おわりに 以上で、画像枚数の制限をかけることができました。 手軽に簡単に実装したい方は、この方法を是非検討してみてくださいね!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Strong parametersの使い方

はじめに 本記事では「strongparametersを使用するとどんな利点があるのか」「基本的な使い方」についてまとめていきます! strongparametersの歴史 rails4から導入された機能。 rails3までMassAssignmentを使用していたが、脆弱性の問題があった。 strongparametersで何ができるのか? strong parametersを用いることで、Action Controllerのパラメータが許可されるまでActive Modelの「マスアサインメント」に利用されることを禁止できます。つまり、多くの属性を一度に更新したい場合は、どの属性のマスアップデートを許可するかを開発者が明示的に指定しなければなりません。大雑把にすべての属性の更新を一括で許可してしまうと、外部に公開する必要のない属性まで誤って公開してしまう可能性が生じるため、そのような事態を防ぐための機能です。[Railガイド] ・開発者が意図的に必要な属性のみを指定し、取得することができる ・マスアサインメント脆弱性の問題を防ぐことができる。 ・意図しない情報の更新や作成を防ぐことができる。 使い方 サンプルコードを使いながらそれぞれのコードについて解説していきます。 ビュー privateを指定した場合以下のようにモデルを指定する必要がある。 「params.require(:user)..」の場合。 <%= form_with model:@user do |form| %> コントローラ [ユーザー情報の取得] private def user_params params.require(:user).permit(:name,:email) end private(呼び出し制限) privateの配下にメソッドを定義することで、クラス外からのアクセスを防ぐことができる。他のクラスではprivate配下のメソッドを使用することができないということ。 ※注意点としては、privateはコントローラの最下部に設置すること。配下にあるメソッド全てをアクセス制限してしまうから。 また、protectedという他のインスタンスでも使用できるようにするメソッドもあるが使用頻度は低い。 params.require(キーのオブジェクトを指定) require(:user)とすることで、特定のオブジェクト(user)を定め、キーを指定して取得することができる。 requireを使用する場合、permitでキーを指定する必要がある。 permit(キーの取得) permit(:キー)とすることで、そのキーの値を取得することができる。 また、permit!とするとrequireで指定したmodelのキーを全てに権限を与え、取得することも可能。 merge(外部の値を取得) paramsでは取得していない値を指定することができる。 params.require(:user).permit(:name,:email).merge(user_id: @current_user.id) [呼び出し方] def create @user = User.new(user_params) end User.new(メソッド)とすることでprivateで定義したメソッドの情報を取得することができる。 この場合、user_paramsで指定したキー全てを取得することができる。 まとめ ・ストロングパラメーターを使用することで取得する値を制限することができ、マスアサインメントの脆弱性を防ぐことができる。 ・メソッドを定義することで簡単に値を取得することができ、リファクタリングにもなる。 補足(param is missing or the value is empty: user) requireを使用した時に以下エラーが発生したのでその対処法について。 params.require(:user).permit(:content...) param is missing or the value is empty: user エラー内容としては、paramsが存在しないか空の状態であるということ。 結論から言うと、 params.permit(:content,:material,:period) require(:user)を消しちゃうとエラーは解決できる。 画像でも確認できるようにパラメーターに値は入っているけど、存在しないという内容のエラーになっている。 原因については、以下の記事がわかりやすかった。 param is missing or the value is empty エラー content: params[:user][:content]... 恐らく、今回の場合だと、上記のようにキーが重複しているため、おきたエラーだと思う。 間違っていたらご指摘いただけると嬉しいです。 参考資料 Railsガイド 【Ruby on Rails】ストロングパラメータって何なの? rubyonrails.org 【Rails】param is missing or the value is empty:について
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

StrongParametersの使い方

はじめに 本記事では「StrongParametersを使用するとどんな利点があるのか」「基本的な使い方」についてまとめていきます! StrongParametersの歴史 rails4から導入された機能。 rails3までMassAssignmentを使用していたが、脆弱性の問題があった。 StrongParametersで何ができるのか? strong parametersを用いることで、Action Controllerのパラメータが許可されるまでActive Modelの「マスアサインメント」に利用されることを禁止できます。つまり、多くの属性を一度に更新したい場合は、どの属性のマスアップデートを許可するかを開発者が明示的に指定しなければなりません。大雑把にすべての属性の更新を一括で許可してしまうと、外部に公開する必要のない属性まで誤って公開してしまう可能性が生じるため、そのような事態を防ぐための機能です。[Railガイド] ・開発者が意図的に必要な属性のみを指定し、取得することができる ・マスアサインメント脆弱性の問題を防ぐことができる。 ・意図しない情報の更新や作成を防ぐことができる。 使い方 サンプルコードを使いながらそれぞれのコードについて解説していきます。 ビュー privateを指定した場合以下のようにモデルを指定する必要がある。 「params.require(:user)..」の場合。 <%= form_with model:@user do |form| %> コントローラ [ユーザー情報の取得] private def user_params params.require(:user).permit(:name,:email) end private(呼び出し制限) privateの配下にメソッドを定義することで、クラス外からのアクセスを防ぐことができる。他のクラスではprivate配下のメソッドを使用することができないということ。 ※注意点としては、privateはコントローラの最下部に設置すること。配下にあるメソッド全てをアクセス制限してしまうから。 また、protectedという他のインスタンスでも使用できるようにするメソッドもあるが使用頻度は低い。 params.require(キーのオブジェクトを指定) require(:user)とすることで、特定のオブジェクト(user)を定め、キーを指定して取得することができる。 requireを使用する場合、permitでキーを指定する必要がある。 permit(キーの取得) permit(:キー)とすることで、そのキーの値を取得することができる。 また、permit!とするとrequireで指定したmodelのキーを全てに権限を与え、取得することも可能。 merge(外部の値を取得) paramsでは取得していない値を指定することができる。 params.require(:user).permit(:name,:email).merge(user_id: @current_user.id) [呼び出し方] def create @user = User.new(user_params) end User.new(メソッド)とすることでprivateで定義したメソッドの情報を取得することができる。 この場合、user_paramsで指定したキー全てを取得することができる。 まとめ ・ストロングパラメーターを使用することで取得する値を制限することができ、マスアサインメントの脆弱性を防ぐことができる。 ・メソッドを定義することで簡単に値を取得することができ、リファクタリングにもなる。 補足(param is missing or the value is empty: user) requireを使用した時に以下エラーが発生したのでその対処法について。 params.require(:user).permit(:content...) param is missing or the value is empty: user エラー内容としては、paramsが存在しないか空の状態であるということ。 結論から言うと、 params.permit(:content,:material,:period) require(:user)を消しちゃうとエラーは解決できる。 画像でも確認できるようにパラメーターに値は入っているけど、存在しないという内容のエラーになっている。 原因については、以下の記事がわかりやすかった。 param is missing or the value is empty エラー content: params[:user][:content]... 恐らく、今回の場合だと、上記のようにキーが重複しているため、おきたエラーだと思う。 間違っていたらご指摘いただけると嬉しいです。 参考資料 Railsガイド 【Ruby on Rails】ストロングパラメータって何なの? rubyonrails.org 【Rails】param is missing or the value is empty:について
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsのリファクタリングの例

リファクタリングとはプログラミングにおいて、プログラムの動作を変えずにコードの内部構造を整理すること、つまりコードを見やすくすることを言う。 修正前 <% if user_signed_in? && current_user.id == @item.user_id && @item.purchase.blank? %> <%= link_to "商品の編集", edit_item_path, method: :get, class: "item-red-btn" %> <p class="or-text">or</p> <%= link_to "削除", item_path, method: :delete, class:"item-destroy" %> <% else user_signed_in? %> <% if @item.purchase.blank? %> <%= link_to "購入画面に進む", item_orders_path(@item) ,class:"item-red-btn"%> これはフリマアプリの一例で、ユーザーのログイン状態において出品した商品の編集、削除ボタンが表示されるか、もしくは購入ボタンが表示されるかの条件分岐を記述したものである。 これだと1行目に「ログインしていればかつ現在ログイン中のユーザー、出現在ログインしているユーザーが商品の出品者であればかつ商品は売れていなければが同じである」というややこしい表記法になっている。 さらに5行目にまたuser_signed_in?があり、6行目に商品は売れていなければの記述で購入画面に進むを表示させる制御をしている。 そこで下記のようにリファクタリングしてみる。 <% if user_signed_in? || @item.purchase.blank? %> <% if current_user.id == @item.user_id %> <%= link_to "商品の編集", edit_item_path, method: :get, class: "item-red-btn" %> <p class="or-text">or</p> <%= link_to "削除", item_path, method: :delete, class:"item-destroy" %> <% else %> <%= link_to "購入画面に進む", item_orders_path(@item) ,class:"item-red-btn"%> <% end %> <% end %> 1行目に大きな条件として"ログインしていれば" かつ "商品は売れていなければ"を記述、2行目に"現在ログインしているユーザーが商品の出品者であれば"をif文のネスト構造で記述して「商品の編集」「削除」を表示させるか 「購入画面に進む」を表示させるかを制御している。 1行にまとめるよりも2行に分けたほうが後々わかりやすく重複しない。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails初学者によるRailsチュートリアル学習記録③ 第1章

目次 1. はじめに 2. 第1章の概要 3. 学習内容 4. 終わりに 1. はじめに この記事は、Rails初学者の工業大学三年生がRailsチュートリアルの学習記録をつけるための記事です。 筆者自体がRailsやWebについて知識が少ないので、内容の解釈などに間違いがある可能性があります。(その時はコメントで指摘してくださると助かります!) Railsチュートリアル内ではRailsの内容以外にも、gitでのバージョン管理やHerokuを使ったデプロイも学習しますが、gitに関しては既に私が学習済みのため学習記録には記述しません。 演習の記録も省略します。 2. 第1章の概要 AWS Cloud9を使った開発環境の準備 必要なgem, プログラムのインストール 最初のアプリケーションの作成 Railsアプリケーションの仕組みについて コントローラとアクションについて ルーティングについて Herokuへのデプロイ Herokuへのデプロイの準備、デプロイ 開発環境の変更を本番環境に反映させる方法 3. 学習内容 1. AWS Cloud9を使った開発環境の準備 AWSのアカウントの作成~ワークスペースの作成までの説明は省略します。 1-1. 必要なgem, プログラムのインストール ①Rubyドキュメントのインストールをしない設定にする gemのインストール時などにドキュメントをインストールしているとその分時間がかかってしまうので、 コマンドラインで$ echo "gem: --no-document" >> ~/.gemrcを実行して、 ドキュメントをインストールしない設定に変更します。 ②バージョンを指定してRailsをインストールする $ gem install rails -v 6.0.3を実行してRailsをインストールします。 インストールできたかどうかは、$ rails -vを実行してバージョンが表示されるかで確認できます。 ③Yarnをインストールする $ source <(curl -sL https://cdn.learnenough.com/yarn_install)を実行して Yarnというプログラムをインストールします。 YarnはJavaScriptのソフトウェアの依存関係を管理するプログラムで、上記のコマンドは クラウドIDEで開発するときに使用できるCDN経由のダウンロード、セットアップとなります。 ネイティブOSで開発するときはOSごとのインストール方法に従うことになります。 以上で、RailsでWeb開発を行う準備は完了です。 1-2. 最初のアプリケーションの作成 ①Rails newを実行してアプリケーションを作成する どのRailsアプリケーションでもrails newコマンドを実行するところから始まります。 実行すると指定したディレクトリにアプリケーションの原型が作成されます。 Railsチュートリアルでは$ rails _6.0.3_ new hello_appと書くことで、バージョンを指定してhello_appという アプリケーションを作成します。 ②Bundlerを使ったgemのインストール Bundlerとは、gemの互換性を保ちながらgemの導入や管理を行ってくれるライブラリです。 Gemfileに使用したいgemやバージョンを記述してbundle installやbundle updateを実行します。 Railsチュートリアルでは、gem 'gem名', 'バージョン'という表記になっています。 この表記方法だと、指定したバージョンのgemをインストールしてくれます。 バージョン指定の方法は他にもあり、gem 'gem名', '>= バージョン'だと指定したバージョン以上で最新のgemを インストールしてくれます。 gem 'gem名', '~> バージョン'だと指定したメジャーバージョンかつマイナーバージョンかパッチバージョンが 最新のgemをインストールしてくれます。 今回はRailsチュートリアル内のGemfileと同じように書き替えて、bundle installを実行します。 ③rails serverの実行 ここまでで、実際に動かせるアプリケーションが作成されたためrails serverを実行することで、 アプリケーションが正しく動くかを確認することができます。 2. Railsアプリケーションの仕組みについて 2-1. コントローラとアクションについて ①コントローラとは コントローラはWebサーバーへのリクエストを処理します。 チュートリアル内でもう少し先に出てくるモデルと通信して、データベースの情報を受け取ったり、 そのデータをビューに渡して動的なページを作ってもらって受け取ったりします。 ①アクションとは アクションとはコントローラ内で定義されるもので、この段階ではrenderメソッドを使って htmlで文字列を表示させています。 application_controller.rb class ApplicationController < ActionController::Base def hello #applicationコントローラ内のhelloアクション render html: "Hello!" #Hello!という文字列を表示 end end 今後、ビュー内で使用する変数を定義するためにも使います。 2-2. ルーティングについて ルーティングとはブラウザからのリクエストをコントローラに振り分ける役割を持ちます。 今のところは、URLとコントローラを対応付けるという認識です。 ここでは、ルートURLと呼ばれるhttp://www.example.com/ または「/」といったURLへのアクセスを どのコントローラに割り振るかを定義します。 routes.rb Rails.application.routes.draw do root 'application#hello' end 上記のコードではルートURLに対するアクセスをapplicationコントローラ内のhelloアクションに割り振っています。 以上が第1章のアプリケーション作成についての内容です。 3. Heokuへのデプロイ gitへのプッシュ、Herokuのアカウント作成は省略します。 3-1. Herokuへのデプロイの準備、デプロイ ①開発環境と本番環境で使うデータベースの設定 Railsチュートリアルの開発環境ではSQliteというデータベースを使用するのですが、Herokuの本番環境では SQliteが使用できないため、PostgressSQLというデータベースを使用します。 その設定をするためにGemfileに変更を加えます。 Gemfile group :development, :test do #開発環境で使用するgemを指定するグループ gem 'byebug', '11.0.1', platforms: [:mri, :mingw, :x64_mingw] gem 'sqlite3', '1.4.1' #SQlite用のgem end group :production do #本番環境で使用するgemを指定するグループ gem 'pg', '1.1.4' #PostgressSQL用のgem end Gemfileを変更したのでbundle installを実行して準備完了です。 ②Herokuのインストール、デプロイ source <(curl -sL https://cdn.learnenough.com/heroku_install)を実行して、Herokuをインストールします。 その後heroku loginコマンドでHerokuにログインします。 Herokuにログインできたら、heroku createというコマンドを実行して、herokuサーバー上に アプリケーションの実行場所を作成します。 その後、git push heroku masterを実行することで、ローカルリポジトリの内容をHerokuにデプロイすることができます。 3-2. 開発環境の変更を本番環境に反映させる方法 これ以降、開発環境で変更を行い、それを本番環境に反映したいときには、 3-1に沿って、git commit -aでコミットを行いgit pushでリモートリポジトリに変更内容をプッシュした後、 git push heroku masterを実行してローカルリポジトリの内容をHerokuにプッシュします。 4. 終わりに 第1章はまだ躓く個所はなく、かかった時間は約4時間ほどでした。 この記事を書くのにかかった時間が約2.5時間程でちょっと長いと感じたので、次から密度を下げたいなと思っています。 以降の内容も、1章分終わったらQiitaに記事を投稿という流れで進めていきます。 (内容が多い章は記事を2つに分けることも考えています)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】RailsにおけるYAMLの基本的な書き方について

背景 railsを学習すると拡張子がymlになっているファイルをよく見かけるため、その書き方について調べてみました。 ※内容に間違いなどがある場合はご指摘をよろしくお願いします。 Yamlとは YAML(YAML Ain’t Markup Language)。構造化されたデータのフォーマットの一種で「.yml」で終わるファイル。他にXML、JSONなどがある。各種設定ファイル、ログファイル、データ保存・交換ファイルとして使われている。 Yamlの書き方 ①スカラー&データ型 文字列: '123'、"abc" 数値: 123、0.01 真偽値: true、false、yes、no、on、off Null: null、 ~ 日付: 2021-01-01 タイムスタンプ: 2021-01-01 00:00:00 +09:00 シンボル: :hoge ②配列 行頭に「-」をつける。「-」のあとは半角スペースを入れる。 - apple - banana - orange # ["apple", "banana", "orange"] 半角スペースでインデントを入れると、ネストさせることもできます。 - fruit - #空の「-」を付ける必要がある - apple - banana - orange #["fruit", ["apple", "banana", "orange"]] ③ハッシュ 「キー: 値」で表す。「:」のあとは半角スペースを入れる。 subject: "Email Changed" #{ "subject" => "Email Changed"} ハッシュと配列のネストも可能です。 - name: Tanaka email: hoge@mail.com - name: Suzuki email: fuga@mail.net #[{"name"=>"Tanaka", "email"=>"hoge@mail.com"}, # {"name"=>"Suzuki", "email"=>"fuga@mail.net"}] ④rubyの記述を書く(ERB形式) 「<%= 内容 %>」という形式で表します。 root: <%= Rails.root.join("tmp/storage") %> #{ "root" => "<%= Rails.root.join("tmp/storage") %>"} ⑤アンカーとエイリアス yamlの記述を保存&呼び出しするために使う記述。アンカーは「&」、エイリアスは「*」。 name: &mark fuga email: abc@mail.com user: <<: *mark #{ "name" => "fuga", "email => "abc@mail.com", "user" => "fuga" } 参考サイト・記事 https://magazine.rubyist.net/articles/0009/0009-YAML.html https://qiita.com/tfrcm/items/5f8e4c5795ce41b214d1 https://zenn.dev/shuichi/articles/7d4a171d87a8e4938f35
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初学者がVue.jsをRailsアプリに組み込めるようになるまでの学習ロードマップ

この記事で得られること はじめに、この記事の目的について。 この記事は一通りRailsアプリケーションを作り終えて、次のステップとして「自分のアプリをモダンなUI/UXを実現したい!」「今っぽいイケてる技術を使ってみたい!」といった動機から、Vue.jsをRailsアプリケーションに組み込みたいと考えている人向けに、学習ロードマップを提供できたら、という狙いです。 以下学習で作成した成果物 私はこれから説明する学習を通して、初学者なりのポートフォリオを作成しました。 ベースはRuby on Rails、ランディングページにVue.jsを使ったアプリです。 StudyReport 最初にたどり着くページはVueのエントリーポイントを作成し、コンポーネントを並べるだけのシンプルな構成です。 またページ内の「Details」から飛べる機能の詳細説明ページは非常に簡単な部分SPAになっています。 こんなレベルでも、Vue.jsを使えるようになりたい!と考えている方には助けになる記事なのではないかと思います。 この記事の対象者 プログラミング初学者 Ruby on Railsは一通り学習し、アプリケーションを作りきった。 JavaScriptは多少触ったことあるかな程度 とにかくVue.jsを入れたい お金はケチりたい 学習ロードアップ 1. まずは公式! やはり最初は公式。 日本語で書かれているのでとてもわかりやすいですし、全ての基礎知識となりますので、やっときましょう。 (自分のアプリ内で応用する時に基礎知識があることが前提となるからです。) 個人的には、「コンポーネントの詳細」の章まで一通りやってみるのかいいかと思います。そのあとは必要に応じてやっていくのが効率が良いかと。 Vue公式 2. ここからはQiita記事 まずはVue.jsのアプリ立ち上げ つくづくQiitaの情報量には感服いたします。 まずはサクッとVue.jsアプリ立ち上げ。 2-1 立ち上げ~vue-router こちらの記事を参考にしていただくと簡単にアプリ立ち上げができます。 またこの記事内ではSPA作成の基本となるvue-routerについて学べます! 2-2 モダンなツールを学ぶ こちらではより見た目をかっこよくできるライブラリなどを学ぶことができます。 vue-typerとかsmooth-scrollとか今っぽくてかっこいいですよね〜 2-3 RailsにVueをいれる方法を学ぶ こちらにはRailsをバックエンドに、Vueをフロントエンドに使ったアプリを作る方法が記載されています。 すでにRailsアプリがあって、追加でVueを入れたい!という場合には「Vue.jsでHello Vue!を表示する」という章から読んでいくのがいいかなと思います。 ここまでで私が作ったレベルのアプリならもうできてしまいますよ! ちなみに私はここまでの学習の副産物としてポートフォリオサイトを作りました。ここでは見やすさの観点からvue-routerは使っていないですが、挙動はそれなりに今っぽい仕上がりになっているのではないかと思います。 3.Railsデータとの連携(筆者積み残し) 本当はRailsのデータと連携して、一つの機能をSPA化できたら尚良しと思っていました。 結論、devise特有のヘルパーなどのVueでの使い方など難しい点が多々あり、今後の積み残しにしていますが、 一度トライはしてみたので、その際に学習した内容をお伝えします。 3-1 いいね機能を作る こちらではRailsをバックエンド、Vueをフロントに使っていいね機能を実装しています。 ここでデータの渡し方などを学ぶことができます。 メモアプリを作る(有料) ここまで公式やQiitaの記事でやってきましたが、だんだん高度になってきたこともあり、情報が複雑化してきました。 そのため私はTechpitの記事を参考に、RailsとVueを使ったメモアプリ作成ハンズオン講座を買いました。 教材はこちら こう言ったベーシックな組み合わせ技術から初めて、高度なSPAを作り込んでいくのが良いのかなと思います。 4.まとめ 正直、あまり高度なことをやれるようになるわけではありません。 しかしVueを使えるようになること、Railsに組み込むことはこの記事の学習ロードマップに沿ってやっていくことで実現できると思います。 ご意見などありましたらコメントいただけると幸いです! 5.出典 Vue.js公式 https://v3.ja.vuejs.org/ (Qiita記事)【超簡単】Vue.jsを使って3時間で自分のホームページを作成&公開する https://qiita.com/abouch/items/35d7a202f3e74c7d4c3e (Qiita記事)Vue.jsでポートフォリオを書く https://qiita.com/shoma3571/items/025a4e8aedeb62b1fed4 (Qiita記事)Ruby on Rails, Vue.js で始めるモダン WEB アプリケーション入門 https://qiita.com/tatsurou313/items/4f18c0d4d231e2fb55f4 (Qiita記事)Rails + Vue.jsでいいね機能を実装する https://qiita.com/TakeshiFukushima/items/a6c698fec648c11eee9a (Techpit)Rails × Vue.js でメモアプリを作成しながらモダンな開発を学ぼう! https://www.techpit.jp/courses/123
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

herokuで動かしている俺のRailsアプリがこんなにメモリを食うわけがない

発端 2021/04/18 ふと気がつくとherokuで運用中のrailsアプリが亡くなっていました。 原因探るの面倒だったので再起動しました。 その後も割と頻繁に死亡していたので、herokuのダッシュボードを確認しました。 すると... ?Memory Usage 100%? なんかメモリが爆上げしているご様子 そして多数のapp crashのログがちらほら 環境 heroku web: Free Dynos worker: Free Dynos Ruby: 2.7.3 Rails: 5.2.5 対応したこと herokuがrubyでのメモリ爆上げ状態の対策をまとめてくださったので、そちらを参考に対応しました。 ありがとうheroku、いいプラットフォームです。 調べてみるとSidekiqで非同期処理を動かしていたのが怪しいみたいな感じでした。 起動時の Worker 数の超過 起動時のWorkerを1にしました。 # config/puma.rb workers Integer(ENV['WEB_CONCURRENCY'] || 2) # CLI $ heroku config:set WEB_CONCURRENCY=1 引用すると 2 つの Puma Worker が原因で、​standard-1x​ dyno が提供できる量を超える RAM が使用されます。これが発生した場合でも、スレッドを使用して、スループットを増大させることができます。または、​dyno サイズをアップグレード​して、実行する Worker の数を増やすことができます。 2つで死が近づくっぽいですね 経過に伴うWorker数の超過 メモリが増加して上限を迎える場合(今回の私の感じで)Puma Worker Killerでプロセスを再起動することでメモリの増加を抑制できます。 gem "puma_worker_killer" PumaWorkerKiller.enable_rolling_restart Worker が再起動すると、数秒間リクエストに応答できないので、繰り返しの再起動がトリガーされると、エンドユーザーは、アプリケーション全体のスループットが低下したときに減速を経験することがあります。再起動すると、スループットは通常に戻ります。 このアプリケーションは非同期処理ではリアルタイム性を特に求めてなかったのでプロセスには容赦なく消えていただきました。 Puma Worker Killerはgemで、指定した条件になったらWorkerプロセスを切るしてくれるイイやつです。 Unicornにも似たようなことができるgemがあったと思います。 環境変数MALLOC_ARENA_MAX=2を指定する https://qiita.com/kazutosato/items/4ab561bf5cc03da75e72 ↑こちらの記事に自分と全く同じ状況の方がいたので参考にさせていただきました。 Herokuでは、上記の2の環境変数MALLOC_ARENA_MAX=2はデフォルトになりました。ただし、2019年9月24日より前に作られたアプリケーションでは自分で設定する必要があります。 らしいです。私のアプリケーションこれより前に作ってた気がしています。 起動時のメモリの超過 こちらは調査で終わったやつですが一応。 derailedというベンチマークのgemで起動時のメモリ使用量をチェックしました。 gem 'derailed', group: :development $ bundle exec derailed bundle:mem これでボトルネックとなりそうなgemを消すという対策です が、Hobby Dynosの512MBを食いつぶすようなものは見つからず... TOP: 67.2734 MiB jemallocでのビルド なんか公式のものよりメモリに優しいアロケータらしい $ heroku buildpacks:add --index 1 https://github.com/gaffneyc/heroku-buildpack-jemalloc.git $ git push heroku master $ heroku config:set JEMALLOC_ENABLED=true 結果 ↑の右の方のダウン(メモリ消費が0になった)の後に対応しました 増え続けていはいない気がするけど、なんか期待してたのと違う とりあえず要経過観察です オチ unicorn起動してたwwwwwwwwwww Procfileでガッツリunicorn起動していました... なんの為に私はpumaの設定をせっせと書き換えていたのだろうか.... unicornのgemもけしました 無事に平和な感じになってそうです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActionCableでのコメント機能について

ActionCableについて ActionCableとは、通常のRailsアプリケーションと同様の記述で、即時更新機能を実装できるフレームワークです。例えば、メッセージやコメントを即時表示させたい場合に使用します 実装について まずは以下のコマンドをターミナルで打ち込んでください rails g channel message このようになれば成功です。 Running via Spring preloader in process 11084 invoke test_unit create test/channels/message_channel_test.rb create app/channels/message_channel.rb identical app/javascript/channels/index.js identical app/javascript/channels/consumer.js create app/javascript/channels/message_channel.js 今回の実装では以下の2つのファイルについて理解する必要があります。 message_channel.rb クライアントとサーバーを結びつけるためのファイルです。 message_channel.jsの役割 サーバーから送られてきたデータをクライアントの画面に描画するためのファイルです では、さっそくコードを書いていきます。 まずは、サーバーとクライアントを結び付けます。 app/channels/message_channel.rb class MessageChannel < ApplicationCable::Channel def subscribed stream_from "message_channel" end def unsubscribed # Any cleanup needed when channel is unsubscribed end end このとき出てくるstream_fromは、ActionCableで用意されているメソッドでサーバとクライアントを関連づけます。この関連づけられたことで作られるデータの経路をboradcast(ブロードキャスト)と言います。 次にコントローラの編集をしましょう app/controller/messages_controller.rb class MessagesController < ApplicationController def new @messages = Message.all @message = Message.new end def create @message = Message.new(text: params[:message][:text]) if @message.save ActionCable.server.broadcast 'message_channel', content: @message end end end 下から四行目に着目してください。 broadcastを通して、'message_channel'に向けて@messageを送信するという意味です。content:@messageの指定ミスに注意してください。 さて、いよいよjsファイルを編集します。 app/javascript/channels/message_channel.js import consumer from "./consumer" consumer.subscriptions.create("MessageChannel", { connected() { // Called when the subscription is ready for use on the server }, disconnected() { // Called when the subscription has been terminated by the server }, received(data) { const html = `<p>${data.content.text}</p>`; const messages = document.getElementById('messages'); const newMessage = document.getElementById('message_text'); messages.insertAdjacentHTML('afterbegin', html); newMessage.value=''; } }); ここで出てくるdataは送られてくる情報を受け取っています。 data.contentで,createアクションで指定したインスタンス(@message)を取り出しています。 あとは、通常のJavascriptと同様です。なお、newMessage.value="";としているのはメッセージ入力・送信後は入力フォームに文字を残しておきたく泣いためです。 あとはビューファイルを作って終わりです。お疲れ様でした! new.html.erb <%= form_with model: @message do |f| %> <%= f.text_field :text %> <%= f.submit '送信' %> <% end %> <div id='messages'> <% @messages.reverse_each do |message| %> <p><%= message.text %></p> <% end %> </div> 終わりに ActionCableの他にAjaxなどの似たような技術もあるので、そこについてはまた今度執筆します!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActionCableでのメッセージ機能について

ActionCableについて ActionCableとは、通常のRailsアプリケーションと同様の記述で、即時更新機能を実装できるフレームワークです。例えば、メッセージやコメントを即時表示させたい場合に使用します 実装について まずは以下のコマンドをターミナルで打ち込んでください rails g channel message このようになれば成功です。 Running via Spring preloader in process 11084 invoke test_unit create test/channels/message_channel_test.rb create app/channels/message_channel.rb identical app/javascript/channels/index.js identical app/javascript/channels/consumer.js create app/javascript/channels/message_channel.js 今回の実装では以下の2つのファイルについて理解する必要があります。 message_channel.rb クライアントとサーバーを結びつけるためのファイルです。 message_channel.jsの役割 サーバーから送られてきたデータをクライアントの画面に描画するためのファイルです では、さっそくコードを書いていきます。 まずは、サーバーとクライアントを結び付けます。 app/channels/message_channel.rb class MessageChannel < ApplicationCable::Channel def subscribed stream_from "message_channel" end def unsubscribed # Any cleanup needed when channel is unsubscribed end end このとき出てくるstream_fromは、ActionCableで用意されているメソッドでサーバとクライアントを関連づけます。この関連づけられたことで作られるデータの経路をboradcast(ブロードキャスト)と言います。 次にコントローラの編集をしましょう app/controller/messages_controller.rb class MessagesController < ApplicationController def new @messages = Message.all @message = Message.new end def create @message = Message.new(text: params[:message][:text]) if @message.save ActionCable.server.broadcast 'message_channel', content: @message end end end 下から四行目に着目してください。 broadcastを通して、'message_channel'に向けて@messageを送信するという意味です。content:@messageの指定ミスに注意してください。 さて、いよいよjsファイルを編集します。 app/javascript/channels/message_channel.js import consumer from "./consumer" consumer.subscriptions.create("MessageChannel", { connected() { // Called when the subscription is ready for use on the server }, disconnected() { // Called when the subscription has been terminated by the server }, received(data) { const html = `<p>${data.content.text}</p>`; const messages = document.getElementById('messages'); const newMessage = document.getElementById('message_text'); messages.insertAdjacentHTML('afterbegin', html); newMessage.value=''; } }); ここで出てくるdataは送られてくる情報を受け取っています。 data.contentで,createアクションで指定したインスタンス(@message)を取り出しています。 あとは、通常のJavascriptと同様です。なお、newMessage.value="";としているのはメッセージ入力・送信後は入力フォームに文字を残しておきたく泣いためです。 あとはビューファイルを作って終わりです。お疲れ様でした! new.html.erb <%= form_with model: @message do |f| %> <%= f.text_field :text %> <%= f.submit '送信' %> <% end %> <div id='messages'> <% @messages.reverse_each do |message| %> <p><%= message.text %></p> <% end %> </div> 終わりに ActionCableの他にAjaxなどの似たような技術もあるので、そこについてはまた今度執筆します!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む