20210827のRubyに関する記事は15件です。

【Rails】carrierwave画像投稿機能 (メモ)

目標 画像投稿機能 開発環境 Rails: 6.1.3 ruby: 3.0.0 mac: os 前提 投稿機能実装済み 投稿テーブルpost 実装 1.Gemfileにcarrierwaveを記述 してインストール Gemfile gem 'carrierwave' bundle installします。 ターミナル $bundle install 2.postテーブルにimageカラム追加 ターミナル $rails g migration AddImageToPosts image:string マイグレーションファイルが生成されます。 imageカラムが追加されているのを確認してマイグレーションします。 class AddImageToPosts < ActiveRecord::Migration[6.1] def change add_column :posts, :image, :string end end ターミナル $rails db:migrate 3.イメージアップローダー作成 ターミナル $rails g uploader image image_uploader.rbファイルが生成される。 4.モデル紐付け postモデルにイメージアップローダーを紐付ける。 app/models/post.rb class Post < ApplicationRecord mount_uploader :image, ImageUploader end 5.コントローラー記述 praivateのpost_paramsにimageを追加。 app/contrllers/posts_controller.erb private def post_params params.require(:post).permit(:content, :title, :image) end 6.ビュー記述 画像投稿フォーム追加。 app/views/posts/_form.html.erb <%= form_with(model: @post)do |f| %> <div> <%= f.label :title, ' タイトル' %> <%= f.text_field :title %> </div> <div> <%= f.label :content, '内容' %> <%= f.text_field:content %> </div> <%= f.label :image, '画像' %> <%= f.file_field :image %> <div> <%= f.submit '投稿'%> </div> <% end %> 画像投稿フォームができました。 これだけでは投稿できないのでimage_tagを使って投稿できるように記述します。 app/views/posts/show.html.erb <h5><画像投稿></h5> <p>タイトル:<%= @post.title %></p> <p><%= image_tag @post.image.url %></p> <p>内容:<%= @post.content %></p> 記述したので投稿できるはずです。 こんな感じで無事投稿でできました。 以上です。 参考 参考にした記事です。 https://qiita.com/k19911848/items/a082cc4e0c0103f935b1
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

to_iメソッドの使い方

to_iとは? 数字の文字列を数値オブジェクトに変換するメソッドです。 また、小数を整数に変換することもできます。 以下、サンプルコードになります。 使用例 オブジェクト.to_i num = "1" p num => "1" (文字列) num.to_i => 1 (整数) puts 100 + "100"  #数値オブジェクト + 文字オブジェクトは計算できない puts 100 + "100".to_i #to_iを使って文字オブジェクト ⇒ 数値オブジェクトに変える ⇒ 200 小数を整数に変えることもできる # 小数として定義 num = 1.0 num.class => Float #整数に変換 num = num.to_i num.class => Integer 参考記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】配列の中のハッシュから値を取得する方法(map)

単一のオブジェクトから持ってくる方法と、 オブジェクトが配列に入っていて、その配列の中から一個一個とりだす方法を紹介します。 1.単一のオブジェクトからデータをもってくる方法 2.オブジェクトが配列に入っているときに、欲しいデータだけをもってくる方法 1.単一のオブジェクトからデータをもってくる方法 # まず、インスタンスを取得 @user = User.find(2) # @userの中身を確認 @user => #<User id: 2, email: "admin1@example.com", last_name: "admin", first_name: "user1", created_at: "2021-08-19 05:52:42", updated_at: "2021-08-19 05:52:42", deleted_at: nil> この中から欲しいデータだけを取得したいとき user.last_name => admin ActiveRecord::Baseを継承したクラスはテーブルの構造を読み取り、自動でgetter,setterを作成する。そのため、カラム名をそのままgetter,setterとして利用ができる userがリレーションを組んでいて、リレーション先のテーブルからデータを持ってきたいときも同じ user.post.title => "今日の晩ごはん" 値はとれるけど、ActiveRecord的に自然ではないデータのとり方 user[:last_name] => admin user.post[:title] => "今日の晩ごはん" 2.オブジェクトが配列に入っているときに、欲しいデータだけをもってくる方法 # まずインスタンスを取得 post = Post.find(2) # postの中身を確認 [28] pry(main)> post => #<AssetMaster:0x000055766365a3e0 id: 2, name: "今日の朝ごはん", post_image: 1, created_at: Thu, 19 Aug 2021 14:52:29 JST +09:00, updated_at: Thu, 19 Aug 2021 14:52:29 JST +09:00, deleted_at: nil> # このpostに紐付いたデータ(image_masters)が配列に入っている(配列の中にハッシュオブジェクトが3つはいっている) [28] pry(main)> post.image_masters => [#<ImageMaster:0x0000557663c32218 id: 2, name: "電子機器", created_at: Thu, 19 Aug 2021 14:52:28 JST +09:00, updated_at: Thu, 19 Aug 2021 14:52:28 JST +09:00, deleted_at: nil>, #<ImageMaster:0x0000557663cb85c0 id: 7, name: "嗜好品", created_at: Thu, 19 Aug 2021 14:52:28 JST +09:00, updated_at: Thu, 19 Aug 2021 14:52:28 JST +09:00, deleted_at: nil>, #<ImageMaster:0x0000557663cb8430 id: 8, name: "エンタメ", created_at: Thu, 19 Aug 2021 14:52:28 JST +09:00, updated_at: Thu, 19 Aug 2021 14:52:28 JST +09:00, deleted_at: nil>] この中から、ImageMasterのnameが配列で欲しい場合(電子機器,嗜好品,エンタメが配列でほしいとき) post.image_masters.map(&:name) => ["電子機器", "嗜好品", "エンタメ"] 補足 このように任意のカラムの配列を取得する方法として「pluck」と「map」の二つのメソッドが存在する。 使い分けの方法は DBから値を取得する場合には「pluck」、既にインスタンス化したオブジェクトから値を取得する場合は「map」 という使い分けが最適です。 詳しくはこちら pluckとmap の違いを調査する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails]フォロー機能導入中にActiveModel::UnknownAttributeErrorというエラー発生

はじめに 本記事では、フォロー機能時に発生した ActiveModel::UnknownAttributeErrorというエラーの解決した方法を記述します。 仲間に助けてもらいながら実装できたため、個人でもアウトプットして身につけたいと思い、記事にしました。 エラー画面 attribute=属性という意味。(Google先生) Relationshipにuser_idという属性は知らん。と怒られました。 確かに、user_idはありません。 しかし、binding.pryでparams[:user_id]の値取れてるじゃないですか...。 と言い訳してみたはいいものの、まあカラムにないわけですからなんとかします。 コード 実際のコードがこれです。 relationships_controller.rb class RelationshipsController < ApplicationController before_action :authenticate_user! def create following = current_user.relationships.build(follower_id: params[:user_id]) following.save redirect_to request.referrer || root_path end def destroy following = current_user.relationships.find_by(follower_id: params[:user_id]) following.destroy redirect_to request.referrer || root_path end end following = current_user.relationships.build(follower_id: params[:user_id])` エラーの内容的にここだよね。と思ったので、もうピンポイントで突き止めていきます。 結論 relationships_controller.rb class RelationshipsController < ApplicationController before_action :authenticate_user! def create following = Relationship.create(follower_id: params[:user_id], following_id: current_user.id) redirect_to request.referrer || root_path end def destroy following = Relationship.find_by(follower_id: params[:user_id], following_id: current_user.id) following.destroy redirect_to request.referrer || root_path end end following = Relationship.create(follower_id: params[:user_id], following_id: current_user.id) Relationshipモデルにcreateメソッドつけて、 カラムであるfollower_idとfollowing_idをセッターにして、 それぞれ値を入れ込めば完了。 敗因 ①Relationship.create(follower_id: params[:user_id], following_id: current_user.id)の形で値を入れることを理解できていなかった。 ②なんとかして、変数を作って入れることしか考えていなかった。 別解として、 カラムをfollowingをuser_idに変えてしまう手もあったようです。 終わりに 完全に仲間に助けてもらい、解決しました。 同じスタートを切ったはずなのに差ができていたことに愕然としたものの、 みんなでディスカッションしながらコードを眺めるのも、楽しいなと感じました。 Railsでフォロー機能を作る方法 【Ruby on Rails】フォロー機能を作ろう(PART2)How to set up a Follower Following system in Ruby on Rails 2つ目はYouTubeですが、 この方の動画はかなり参考になるかと思います。 今日は週末ですが、 明日も頑張ります!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】ActiveRecord::RecordNotFound (Couldn't find Order without an ID)の対処法

症状 RailsAPIでメソッドを作成していたところ、以下のエラーメッセージが表示されてしまいました。 翻訳すると、「IDのないHogeが見つかりませんでした」 error Completed 404 Not Found in 1ms (ActiveRecord: 0.0ms | Allocations: 158) ActiveRecord::RecordNotFound (Couldn't find Hoge without an ID) メソッドにパラメータは以下です。 parameter Parameters: {"params"=>{"id"=>12}, "hoge_id"=>"12", "hoge"=>{}} 該当のメソッドは以下です。 hoge.rb class OrdersController < ApplicationController def update hoge= Hoge.find(params[:id]) render json: { hoge: hoge }, status: :ok end end 解決方法 パラメータを適切に受け取れるように、paramsの指定先を修正したら解決しました。 パラメータの受け取り方がよくなく、結果、DBにfindしようとしたときに、id指定ができていなかったため、「IDがないよ」と怒られていたようです。 hoge.rb class OrdersController < ApplicationController def update hoge= Hoge.find(params[:hoge_id]) render json: { hoge: hoge }, status: :ok end end 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】ransackによる簡易的な検索機能実装

概要 ransackのシンプルモード(Simple Mode)を利用した簡易的な検索機能を実装しました。備忘録として記録します。 環境 Ruby(バージョン2.6.5) Rails(バージョン6.0.0) mysql2(バージョン0.5.3) 実現したいこと 登録してある顧客のリストに対して、氏名(last_name, first_name)と会員ID(member_id)による検索を可能にする。 過程 1. ransackの導入 Gemfile gem 'ransack' -zsh % bundle install 2. コントローラー customers_controller.rb def index @customers = Customer.order("created_at DESC") @search = Customer.ransack(params[:q]) @customers = @search.result end .order("created_at DESC")で顧客のリストを登録の新しい順に並べています。 params[:q]には検索パラメータが渡されるため、@search = Customer.ransack(params[:q])とすることで、検索オブジェクト@searchが作成されます。そして、@customers = @search.resultによって検索結果が得られます。 3. ビュー customers/index.html.erb <%= search_form_for @search , html: {class: "search-form"} do |f| %> <%= f.search_field :last_name_or_first_name_or_member_id_cont, class:"input-box", placeholder:"顧客検索" %> <%= button_tag type: :submit, class: "search-button" do %> <%= image_tag "search.png", class:"search-icon" %> <% end %> <% end %> ransackの利用においてform_forは、search_form_forと記述します。引数に検索オブジェクト@searchをとることで検索フォームを作成できます。 今回のシンプルモード(Simple Mode)検索は、カラム名と述語(Predicate)を組み合わせてSQLを作成し、検索する方法です。 f.search_field :カラム名_contにより、指定したカラム名に対してLIKE句を利用した部分一致検索が可能になります。[述語(Predicate)部分→cont:LIKE句を使った曖昧検索] また、_or_を用いてカラム名を繋げることで複数のカラム名による検索が可能となります。 おわりに 今回はransackを利用した簡易的な検索機能を実装してみました。 今後は、セレクトボックスを用いた検索などより複雑な検索機能の実装に取り組みたいと思います。 また、より良い実装方法や記事内に間違いなどがありましたらご教示ください。 参考 ransack Ransackで簡単に検索フォームを作る73のレシピ Railsガイド:フォームヘルパー
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

親モデルのActiveModel::Serializer内で子モデルのActiveModel::Serializerを指定する

実行環境 macOS 10.15.7 (19H1217) Ruby 2.6.7 Rails 6.0.3.7 active_model_serializers 0.10.12 前提 AuthorモデルとBookモデルはhas_many・belongs_toの関係にある。 以下の設定が有効になっている。 config/initializers/active_model_serializers.rb ActiveModelSerializers.config.default_includes = '**' やりたい事 AuthorモデルのインスタンスをJSONとして取得する際には,AuthorSerializerを使用する。 BookモデルのインスタンスをJSONとして取得する際には,BookSerializerを使用する。 AuthorモデルのインスタンスをJSONとして取得する際には,そのインスタンスが持つBookモデルのインスタンスも取得する。 やり方 以下のようにすることで,異なるActiveModel::Serializerを結びつけることができます。 app/serializers/author_serializer.rb class AuthorSerializer < ActiveModel::Serializer attributes :id, :name, :email, :books def books ActiveModel::SerializableResource.new(object.books, each_serializer: BookSerializer) end end app/serializers/book_serializer.rb class BookSerializer < ActiveModel::Serializer attributes :id, :title end 参考文献
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

オブジェクト指向とは何なのか?(今理解できる範囲でまとめてみる) 初心者なりに

オブジェクト指向 これまで何回か目にし、その度に調べてるけどよく理解できていません。 こういうのって、実務経験積んでくうちに理解できてくるものなんじゃないのかな・・・と 現状あんまり理解できていない私としては思います。 Rubyはオブジェクト指向言語、JavaもJavascriptもそうらしいです。 で、オブジェクト指向って一体何なのか。。 効率よく開発するための考え方 何かのコード記述のルールがあって、それがオブジェクト指向っていうわけではなく、、 「効率よく開発をするための考え方や概念」だそうです。 特徴①カプセル化 「オブジェクト」というものが、データやメソッドなんかを一つのカプセルにまとめてしまうようなイメージです。 カプセル化されてしまうと、外からは中がどうなってるか見えません。 情報がカプセルにより「隠されている」これがカプセル化です。 カプセル化することで他からの影響を受けにくく、カプセルごと分けて考えることができます。 特徴②継承 同じようなプログラムはまとめていこうという考え方。 よく例に出てくるのが車ですね。 車という上位クラス(スーパークラス)から派生したものが、 乗用車やバス、トラックです。←下位クラス(サブクラス)になります。 乗用車もバスも結局は車なので、上位クラスの特徴を受け継いでることになります。 これが継承です。 特徴③ポリモーフィズム 同じメッセージを複数のオブジェクトに送った結果それぞれが、 固有の処理を行うこと。これをポリモーフィズム(多態性といいます。) 車でいうと、バスはバスの機能をするよねーっていうことです。 まとめ カプセル化・・他から影響受けない、破壊されない 継承・・同じようなプログラムはまとめていこう ポリモーフィズム・・汎用性を持つ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

internship

インターン Peersに追加したい機能 自由記入欄に<br>タグなどの改行タグを入れなくても改行できるようにしたい。 現状、コードブロックや<br>などのhtmlタグを入れないと改行できないようになっている。 Userの一覧ページにページネーション機能を用意したい。 画像などを表示しているため読み込むのに時間がかかる。 ページを分割することにより、ユーザが情報を見やすくできる。 表示速度が上がる。 実装 1.  E-R図の作成 既存のプロジェクトの改良なのでまずはデータベース関係の構造を理解しようと思い設計図(E-R図)などを提供してもらおうとメンターに相談。 -- このプロジェクトには設計書(E-R図)がなかった。メンターの串崎さんから自動でE-R図を生成できるgemがあることをご教授いただき、急遽追加したい機能の最上位にE-R図を作成するタスクを追加。 実装中に、どうせならカラムの追加、削除などのデータベースを変更する度にE-Rを最新のものに再生成する機能も追加したいと思い実際に実装した。 具体的には`db:migrate`を実行後にE-Rを再生成するタスク処理を実装。 2. リファクタリング users_sessions_controllers.rbを見ていると不要な変数を定義している箇所や変数のスコープをより制限できそうなコードを見つけたのでリファクタリングを行った。 実際にブラウザをポチポチしながら挙動を確認し問題なかった。 ぽちぽちするのもいいがテストコードを作成し挙動確認をより正確かつ楽にしたいと思い、挙動確認のためのテストコードをコーディングした。 (普段テストコードを書きたいとは思ってはいたが後回しになっていたのでいい機会だった。) あまりテストコードを書いたことがなかったのでとても時間を割くことになりました。 3. 自由記入欄にタグなどの改行コードを入れなくても改行できるようにしたい。 userの詳細画面にアクセスし、自己紹介文を表示する直前に改行コード(\r, \n, \r\n)を<br>タグに置き換える関数を実行させることによりこの機能を実現することができた。 *こちらも挙動確認のためテストコードを作成しました。 4. ページネーション機能 Userの一覧ページにページネーション機能を用意したい。 gemのpagyを使用して実装しました。 ~pagyを選定した理由~ - 元々はメジャーなgemkaminariを使用する予定だった。 - しかしpagyはkaminariよりも 処理速度が速い・ 軽い・オブジェクト数が少ない(簡単に実装ができる) といったような良いとこ尽くしだった。 peersで採用されているcssフレームワークbulmaとも相性が良い 感想 今回はとてもテストコードに時間を割いた。 前々から集中的にテストコードを書いてみたいと思っていたのでとてもいい機会だった。  追加機能を考えるのにとても苦しんだ。 例: 全員が欲しい機能を選ぶのにとても頭を悩ませた。。 (自由記入欄にタグなどの改行コードを入れなくても改行できるようにしたい。) 1人につき1メンターが必ずついていたのでとても開発しやすかった。 どんな質問でも詳しく教えていただいたのでとても助かった。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Internship

Peersに追加したい機能 自由記入欄に<br>タグなどの改行タグを入れなくても改行できるようにしたい。 現状、コードブロックや<br>などのhtmlタグを入れないと改行できないようになっている。 Userの一覧ページにページネーション機能を用意したい。 画像などを表示しているため読み込むのに時間がかかる。 ページを分割することにより、ユーザが情報を見やすくできる。 表示速度が上がる。 実装 1.  E-R図の作成 既存のプロジェクトの改良なのでまずはデータベース関係の構造を理解しようと思い設計図(E-R図)などを提供してもらおうとメンターに相談。 -- このプロジェクトには設計書(E-R図)がなかった。メンターの串崎さんから自動でE-R図を生成できるgemがあることをご教授いただき、急遽追加したい機能の最上位にE-R図を作成するタスクを追加。 実装中に、どうせならカラムの追加、削除などのデータベースを変更する度にE-Rを最新のものに再生成する機能も追加したいと思い実際に実装。 具体的にはdb:migrateを実行後にE-R図を再生成するタスク処理を実装。 2. リファクタリング user_sessions_controllers.rbを見ていると不要な変数を定義している箇所や変数のスコープをより制限できそうなコードを見つけたのでリファクタリングを行った。 実際にブラウザを操作しながら挙動を確認し問題なかった。 手を動かして挙動確認するのもいいがテストコードを作成し挙動確認をより正確かつ楽にしたいと思い、挙動確認のためのテストコードをコーディングした。 (普段テストコードを書きたいとは思ってはいたが後回しになっていたのでいい機会だった。) あまりテストコードを書いたことがなかったのでとても時間を割くことになりました。 3. 自由記入欄にタグなどの改行コードを入れなくても改行できるようにしたい。 userの詳細画面にアクセスし、自己紹介文を表示する直前に改行コード(\r, \n, \r\n)を<br>タグに置き換える関数を実行させることによりこの機能を実現することができた。 *こちらも挙動確認のためテストコードを作成。 4. ページネーション機能 Userの一覧ページにページネーション機能を用意したい。 gemのpagyを使用して実装。 ~pagyを選定した理由~ 元々はメジャーなgemkaminariを使用する予定だった。 しかしpagyはkaminariよりも 処理速度が速い・ 軽い・オブジェクト数が少ない(簡単に実装ができる) といったような良いとこ尽くしだった。 peersで採用されているcssフレームワークbulmaとも相性が良い 感想 今回はとてもテストコードに時間を割いた。 前々から集中的にテストコードを書いてみたいと思っていたのでとてもいい機会だった。  追加機能を考えるのにとても苦しんだ。 例: 全員が欲しい機能を選ぶのにとても頭を悩ませた。。 (自由記入欄にタグなどの改行コードを入れなくても改行できるようにしたい。) 1人につき1メンターが必ずついていたのでとても開発しやすかった。 どんな質問でも詳しく教えていただいたのでとても助かった。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby on rails]ゲストログイン機能 ゲストログインは削除、編集されないようにする

ゲストログインは作っておいた方が良い! ゲストログイン押したら、ログインできちゃう便利機能です。 就職、転職活動でポートフォリオを外部の方に見せる場合には、作っておいた方が良いらしいです。 ゲストユーザーを作成せず、これでログインしてくださいとemail,passwordを提示したところで、 少し面倒なので見てもらえない可能性があります。 すぐ実装できるので、ゲストログインは作っておくべきだと思います!!!! (他の人のポートフォリオ触ってみてもそうですが、 ゲストログインがないと、やっぱりすごく面倒に感じます。) とても参考にした記事 気をつけないと、すぐ壊れる!! 今回ゲストログイン機能を実装しました。実装自体はうまくいったのですが、、 気をつけないとゲストログイン機能は簡単に壊れていきます。 落とし穴としては今のところ以下2点だと認識しています。 ①ゲストログインは、退会(削除)ができないようにする! ②ユーザー情報の編集もできないようにする! 私の場合、新規登録時に入力させる情報は以下の通りになっています。 ルーティングをかく Rails.application.routes.draw do mount RailsAdmin::Engine => '/admin', as: 'rails_admin' devise_for :users, controllers: { registrations: 'users/registrations', sessions: 'users/sessions', } #ここ追記しています!!!!! devise_scope :user do post 'users/guest_sign_in', to: 'users/sessions#guest_sign_in' end namespace :departments do resources :searches, only: :index end 省略 [devise_scope]は、deviseに新しくルーティングを追加したい場合に使います。(これを使わないとエラーが発生します。) devise_scope :users do get 'ルーティング情報', to: 'users/registrations#アクション' end コントローラー記述 def guest_sign_in user = User.guest sign_in user redirect_to posts_path, notice: 'ゲストユーザーとしてログインしました。' end モデルファイル記述 user.rb def self.guest find_or_create_by!(name: 'ゲストユーザー', email: 'guestda@example.com', join_year: '新入社員', department_id: 1, is_valid: true) do |user| user.password = SecureRandom.urlsafe_base64 end end ゲストログインボタン <li class="nav-item"> <%= link_to "ゲストログイン", users_guest_sign_in_path,class:"btn btn-light fas fa-seedling",method: :post %> </li> ひとまず終わり! ここまででゲストログインはできなくなったかと思います。 あとは、ゲストログインを削除、編集できないようにします。 退会させないようにする ルーティング devise_for :usersになってる場合は、書き換えてください。 devise_for :users, controllers: { registrations: 'users/registrations' } 削除しようとしたら、トップ画面へリダイレクト 私は論理削除にしています。 app/controllers/users_controller.rb def destroy_confirm @user = current_user end def destroy_user @user = current_user if @user.email == 'guestda@example.com' reset_session redirect_to :root else @user.update(is_valid: false) reset_session redirect_to :root end end もしゲストユーザーが退会処理をしようとしたら、 ログアウトさせトップページにレダイレクトさせます。 編集させないようにする ユーザー情報編集されると、 私の場合、「部署」「クラス(新入社員)」とか変更されると、 ゲストログインが壊れました。 なので、ゲストユーザーの場合には、 編集ページが表示されないようにしました。 edit.html.erb <% if @user.email == 'guestda@example.com'%>  <p>ゲストユーザーはユーザー情報の編集ができません。</p> <% else %>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[axios] ファイルダウンロードができない or 空ファイルになってしまう現象の解消

フロント側はReact、サーバーサイドはRailsでファイルダウンロードが うまくいかないケースがあり、それを解消した記事内容になります。 症状としては、axiosのissueにあったこのケースに当たります。 Github | axios/axios | Empty response when responseType is blob or arraybuffer. サーバーサイドとフロント部分の結合部分なので、 原因の特的ができていなくて引っかかってる人が多そうですね。 私のケースの場合は、railsでheadの記述が不要だったのですが、 それだけじゃよくわからないと思います。 実装をみながら解消方法をみていきましょう。 フロント側の記述 フロント側は以下のようなコードにしています。 $ yarn add file-saver import { saveAs } from 'file-saver'; ~~ export const fileDownload = () { axios .get(url, { ~~, responseType: 'blob', }) .then((response) => { const blob = new Blob([response.data], { type: response.data.type, }); saveAs(blob, downoloadFileName); }); } (ちなみにaタグにdownload属性をつけるやり方もあります。) これでフロント側はOKです。 ただ、空ファイルをダウンロードしてしまう場合があります。 const blobの上でブレイクポイントで止めて見ると、以下のような感じです。 Blobのサイズが0になっていたり、画像やpdfをダウンロードしようとしているのですが、typeがtext/xmlになっています。 こんなときはサーバーサイド側に問題があります。 サーバーサイド側の記述 私の触ったコードのケースではrailsでsend_data()を使ってfileの実体を送っていました。 記述は以下のような感じにもともとなっていました。 def download upload_file = UploadFile.find(file_params) file = upload_file.file.blob.download # モデルでhas_one_attached :fileを記述 if send_data(file, disposition: 'attachment', filename: upload_file.file.blob.filename.to_s, ~~ ~~ head :no_content # これがあるとうまくいかない。 else ~~ end end send_data()の引数自体は問題ないのですが、このコードはうまくいきませんでした。 head :no_contentが不要でした。 head :no_contentを削除すると、フロント側のレスポンスが以下のように変わります。 Blobのsizeやtypeにちゃんと値が入ります。 ダウンロードした画像も表示できました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on rails】JavaScript 非同期通信のコメント機能でエラーメッセージを出す バリデーション

初めに 非同期通信でのコメント機能は実装ずみで、「401字以上のコメント」はNGというバリデーションは、 かけていたものの、エラーメッセージが出るようにしていませんでした・・・。 少し実装に苦労はしたものの、非同期通信への理解が深まったのでまとめていきます!! バリデーションをかけておく app/models/post_comment.rb class PostComment < ApplicationRecord default_scope -> { order(created_at: :desc) } # あるコメントに紐づくユーザーも記事も1 belongs_to :user belongs_to :post validates :comment, presence: true, length: { maximum: 400 } end 一応マイグレーションファイルも。 db/migrate/20210801122808_create_post_comments.rb class CreatePostComments < ActiveRecord::Migration[5.2] def change create_table :post_comments do |t| t.text :comment, null: false t.integer :user_id,null: false t.integer :post_id,null: false t.timestamps end end end app/views/post_comments/_comment.html.erb <%= form_with(model:[post, post_comment], remote: true) do |f| %> <%= f.text_area :comment, rows:'2',placeholder: "感想や疑問点をコメントで伝えましょう",required: true,class:"form-control" %> <%=f.submit "コメントする",class:"mt-2 btn btn-outline-secondary btn-block btn-sm"%> とりあえず、ここまでやると空欄での投稿に対しては以下のように出てきます。 ただ、401文字打ってもバリデーションには引っかかるものの何も出てこないという状況です。 コントローラーで保存できなかった場合の記述を書く! controllers/post_comments_controller.rb def create post = Post.find(params[:post_id]) @comment = current_user.post_comments.new(post_comment_params) @comment.post_id = post.id @post = Post.find(params[:post_id]) if @comment.save # ユーザーステータス無効で、投稿者とコメント者が等しいとき if current_user != @post.user && @post.user.is_valid == true @post.create_notification_by(current_user) end @post_comment = PostComment.new else render 'error' end end 通知機能も実装してるのでわかりにくくなっているかもしれません・・・・すみません。 コメントがバリデーションに引っかかってしまい保存されなかったら、 render 'error'というところがポイントです!!! さてrender先にいきます。 error.js.erb views/post_comments/error.js.erb $("#comments-error").html("<%= j(render 'layouts/errors', obj: @comment) %>"); コメントが401字でバリデーションに引っかかってるので、@commentの持ってる値としては ”false"になっています。 そしてここの記述としては、idがcomments-errorとなっているどこかに、 <%= j(render 'layouts/errors', obj: @comment) %>を渡すという意味 です。 ちなみに'layouts/errors'の中身はこんな感じになっています。 <% if obj.errors.any?%> <div class="text-center" style="color:red;"> <%=obj.errors.count %>件のエラーが発生しました。<br> <% obj.errors.full_messages.each do |message| %> <%= message %> <% end %> </div> <% end %> さてこのエラー文を差し込む、id = comments-errorの箇所を作りましょう。 エラーメッセージを出す app/views/post_comments/_comment.html.erb #ここです!!!! <div id ="comments-error"></div> <%= form_with(model:[post, post_comment], remote: true) do |f| %> <%= f.text_area :comment, rows:'2',placeholder: "感想や疑問点をコメントで伝えましょう",required: true,class:"form-control" %> <%=f.submit "コメントする",class:"mt-2 btn btn-outline-secondary btn-block btn-sm"%> <% end %> <div id ="comments-error"></div>という箇所を作成しました。 これでコメント欄のすぐ上にエラーメッセージができます。 まとめ:非同期通信のエラーメッセージの流れ コメントがバリデーションに引っ掛かり保存されない ↓ errorのjsファイルに飛ぶ ↓ jsファイルは指定されてるidに、html以下を差し込む ↓ 該当のidが記載されてる箇所で、html以下を受け取り表示する。 要するに、普段は <div id ="comments-error"></div>なってるところが、 <div id ="comments-error">render 'layouts/errors', obj: @comment</div> になってくれて、エラー文が出てくると! そもそも非同期通信とは.. 最後に書くことはでなはいですが、簡単にまとめていきます。 簡単にいうと「データを送信したら、もう画面を書き換えてもらう」ということです。 サーバーからの結果は待ちません。 通常であればちゃんと応答待ちますが、非同期通信は待ちません! メリットとしては待つ必要が無いから、早いということです。 サーバーが処理してる間に、操作ができます。 「あとやっといて〜」って感じでしょうか。 最後に 非同期通信がうまくいかないときって、大体スペルミスのような気がしますので、 スペルミスにご注意ください!!!!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on Rails】デプロイ後、本番環境で画像が表示されない不具合を解消する方法

対象者 ローカル環境で表示される画像が本番環境で表示されない方 目的 本番環境でも問題なく画像を表示させる 実際の手順と実例 1.前提 ruby 2.5.1 rails 5.2.5 AWS app/assets/imagesの中に画像が保存されている 自動デプロイできている状態 2. 結論 変更前 <img src="assets/search.png" alt="#"> ↓↓↓ 変更後 <%= image_tag asset_path("search.png", alt: "") %> これで実装完了です! 3.原因 本番環境では、画像もコンパイルされることが原因のようです。 ※コンパイルとは、ソースコードを機械語に翻訳する作業のこと 本番環境ではパス名と画像の名前が変わっちゃうので 両方に対応できるasset_path()を使い、解決できました! 参照 【ちゃんと理解してる?】コンパイル、ビルド、デプロイの違い 投稿者コメント 開発環境で表示されていたのに本番環境で反映されていないと血の気が引きますよね。。。笑 上記変えるだけで簡単に解決できます! My Profile プログラミング学習歴3ヶ月目のアカウントです! プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。 また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。 もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on Rails】gem, bundlerって?

この記事について この記事は、筆者がRuby on Railsを学習・使用する中で疑問に思ったbundle コマンドについて、どういった意味があるのかという内容をまとめていきます。 まだまだ初学者ではあるので、なにか間違った理解等ございましたらぜひご指摘いただけますと幸いです。 bundlerとは プロジェクト内で使用するgemのパッケージ管理ツール。 gemのバージョンやgemの依存関係を管理してくれる「gem」 bundlerの特徴 bundlerを使ってgemをインストールすると、gem同士の互換性を保ってくれる。 Gemfileという1つのファイルにgemを書くので、gemの管理がしやすい Gemfileを使ってアプリごとにgemを管理できる 環境ごとにインストールするgemを管理できる gemの互換性を保ってくれる。Gemfileさえ共有すれば複数人での開発でもエラーを起こさない 参考 https://pikawaka.com/rails/bundler つまりgemを複数使っている場合に発生するgem同士の依存関係を、ひとまとめに管理してくれる便利なgemという理解で問題はないっぽい。 gemとは gemとはrubyのライブラリのこと。 gemはRubyGemsと呼ばれるRuby用のパッケージ管理システムで管理されており、RubyGemsが提供するgemコマンドを通じてインストール等ができる。 パッケージ管理システムは各言語ごとに用意されている。 Python → pip Java → maven node.js → npm Gemfileとは railsアプリで利用するgemの一覧を整理(記述)するファイル。 bundle install コマンドが実行されると、このGemfileに記載されているgemの一覧を参照し、まだインストールされていないgemがあればインストールを実行してくれる。 Gemfile.lockとは Gemfileをもとに実際にインストールされたgemの一覧とバージョンが記載されたファイル。 Gemfile.lockには依存関係にあるgemも含め、bundlerによってインストールされたすべてのgemとそのgemのバージョンが記載されている。 Gemfileをもとに、bundlerによってインストールされたgemの結果が出力されるファイル。 そのため、Gemfile.lockを手動で更新することはない。 bundle install やbundle update を実行することで自動更新される。 まとめ gem rubyのライブラリ(便利機能ツール) Gemfile Ruby on Railsアプリで使用するgemを記述してまとめたもの Gemfile.lock bundle installなどによって、実際にインストールされたgemの結果が出力されるファイル 参考 https://qiita.com/nishina555/items/1b343d368c5ecec6aecf https://nishinatoshiharu.com/difference-gemfile-gemfilelock/ https://qiita.com/kamohicokamo/items/ded4cad5be1778547640
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む