20210910のRubyに関する記事は10件です。

Rails Tutorialで詰まったところのまとめ 第1章

◎コードをWebページに反映させるには「git push heroku」をターミナルで実行(デプロイ)しなければならない ◎「rails server」を実行する際は、「cd ~/environment/hello_app/」でカレントディレクトリを変更してあげる必要あり ◎「heroku create」ができるのは5つまで ▶ 5つ作成したら「heroku apps」でappIDを確認して、「heroku destroy --app 」で削除する ◎リスト1.19 「bundle install --without production」を実施する際は、「cd ~/environment/hello_app/」でカレントディレクトリを変更してあげる必要あり
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】Ruby on Railsのform_withを分かりやすく書き直してみる

Ruby on Railsでよく使うform_withですが、初めて見た時に何が書いてあるのかさっぱり分かりませんでした。 今は書いてあることが少しわかるようになったのでその備忘録です。 実行環境: Ruby on Rails 6.0 まずは簡単なフォームの例 例えばnewアクションに対応したviewである new.html.erbでよく見かけるこんな例文があります。 <%= form_with model: @user, url: users_path do |f| %> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "name" %> <%= f.submit "登録" %> <% end %> これは入力ボックスが一つだけ付いたフォームです。 RubyとRuby on Railsに慣れていないとこれがRubyの文法として正しいのか分かりませんよね。 これはもう少し変形してみると分かりやすくなります。 フォームを分かりやすく変形する <% %>は.erbの中でrubyの文を書く時に必要な物になります。まずは見やすくするために<% %>をはずします。 form_with model: @user, url: users_path do |f| f.label :name f.text_field :name, autofocus: true, autocomplete: "name" f.submit "登録" end まだ見にくいですね。 rubyは()が省略可能です。次は省略されている()を戻してみます。 form_with( model: @user, url: users_path ) do |f| f.label( :name ) f.text_field( :name, autofocus: true, autocomplete: "name" ) end これで少しはやっていることのイメージがしやすくなったかと思います。 form_withというメソッドを呼んでいたということです。そして、form_withの後ろに書かれていた model: @user, url: users_path これらは引数だったということです。 form_withの引数の書き方について 次はform_withの引数についてです。 form_withは2つの引数がありますが、変わった書き方をしています。 model: @user url: users_path この書き方の意味が分かりませんよね。 これは挿入先を指定した引数です。 rubyはどの引数にどんな値を入れるのかを指定することができます。 def add(arg1:, arg2:) p "arg1=#{arg1}" p "arg2=#{arg2}" end def test add(arg2:50, arg1:100) end #------- 結果 "arg1=100" "arg2=50" この例のaddメソッドの呼び出し方と同じです。 この場合、順番に関係なく、arg1に100、arg2に50が入ります。 form_withの例に話を戻します。 model: @user url: users_path この2つは modelという引数に@userを、urlという引数にusers_pathを入れていることになります。 引数は普通なら順番通りに入れないとだめですが、挿入先を指定することで順番を意識することなく引数に値を入れることができるようになります。 uses_pathは何? 次に疑問に思うのが、users_pathですよね。 パスというと、http://xxxx.com みたいな形式ですが、 users_pathとはどこで定義されていて、どこのurlにリンクされているのでしょうか? これはプリフィックスと呼ばれるもので、以下の記事に書いています。 こちらもぜひ参考にしてください。 まとめ ここまで来ると何をしているかわかったのではないかと思います。 <%= form_with model: @user, url: users_path do |f| %> <%= f.label :name %><br /> <%= f.text_field :name, autofocus: true, autocomplete: "name" %> <%= f.submit "登録" %> <% end %> まずはform_withメソッドでhtmlのformタグを出力します。 次にlabelメソッドでhtmlのタグを出力。 次にtext_fieldメソッドでhtmlのテキストボックスのタグを出力。 sumitメソッドでhtmlの登録ボタンを出力しているということです。 rubyの省略表記は便利だけど、初心者には分かりにくいですね…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コントローラーで定義した値をJSに受け渡す

開発環境 OS:macOS Big Sur 11.2.2 Ruby:2.6.5 Ruby on Rails:6.0.0 テキストエディタ:Visual Studio Code つまづいたこと 投稿の詳細画面から非同期通信でDB更新をしたいと考えたときに、更新に必要な値を更新アクションを定義しているコントローラーに渡せず詰まった。 コントローラーからビューファイルに値を渡すときはインスタンス変数を定義するが、JavaScriptへはどうしたらいいのだろう?と思い調べてみた。gonというgemの導入により実現できるらしい。 実践したこと gonは簡単にJSファイルにデータを受け渡すために作られたgemらしい。(と、いうことは難しい手順を踏めば使わなくてもできるということか・・・) 使い方は、 ①まずgemファイルにgonを定義 gem 'gon' ②gemをインストール % bundle install ③includeの記述を追加 下記の通り、headのapplication.js読み込みより前に追加する application.html.erb <head> ~ <%= include_gon %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> ~ </head> これで準備は完了。あとは、 ④受け渡したい値を「gon.〜」という名前で変数定義する recipes_controller.rb def show # JSに渡す変数を定義 gon.receipe_id = @recipe.id end ⑤受け取ったJSファイルで使用 clip.js // clipコントローラーへのリクエスト const XHR = new XMLHttpRequest(); const URL = `/recipes/${gon.receipe_id}/clips` XHR.open('POST', URL, true); XHR.responseType = "json"; XHR.send(); 以上。意外と簡単にできる。 gonのその他の機能について せっかくなので公式ドキュメントを見ていたら、`「gon.watch.〜」という指定の仕方を見つけた。 どうやら値の一定間隔での置き換え・リフレッシュに使う模様。 今回は利用しなかったが、更新したDBのカウントを定義して、リアルタイムでカウント表示したりというときに使えそう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【コピペ】Railsで選択肢を追加していく方法

Ruby on Railsで選択肢を追加していく方法 実装後参考サイト https://vlogmatome.herokuapp.com/posts/new 目次 1.コントローラーを準備する 2.モデル・データベース周り 3.viewのコード 4.ルートをかく 実装 1.コントローラーを準備する まずはコントローラーを準備します。 今回はブランドを投稿していくWebサイトを作成します。 ブランドの選択肢を投稿ごとに追加していきます。 ブランドの投稿はpostsコントローラー。選択肢の追加はbrandsコントローラーで行っていくこととします。 それでは早速コードを書いてみましょう。 posts_controller.rb class PostsController < ApplicationController def index @posts = Post.all @brands = Brand.all @brand = Brand.where(brand:"") end def new @post = Post.new @brand = Brand.new end def create post = Post.new(post_params) if post.save redirect_to :action => "index" else redirect_to :action => "new" end end private def post_params params.require(:post).permit(:brand, :brand_id) end end brands_controller.rb class BrandsController < ApplicationController def index @brands = Brand.all end def create brand = Brand.new(brand_params) if brand.save redirect_to action: "index" else redirect_to action: "new" end end private def brand_params params.require(:brand).permit(:brand, :brand) end end 2.モデル・データベース周り まずはpostsテーブルにinteger型でbrandというカラムとbrand_idというカラムを作成します。 次にbrandsテーブルにstring型でbrandをいうカラムを作成してください。 準備ができてらそれぞれのモデルに以下のコードを書いてみましょう。 モデルの関連づけを行います。 posr.rb class Post < ApplicationRecord belongs_to :brand end brand.rb class Brand < ApplicationRecord has_many :posts end 3.viewのコード 続いてはveiwページです。 posts/index.html.erb <div class="posts-container"> <% @posts.each do |t| %> <br> <% t.brand %> <% end %> <h2>Brand別一覧</h2> <% @size = @brands.length - 1 %> <% for b in 0..@size do %> <%= @brands[b].brand %> <% @brands[b].posts.compact.each do |t| %> <% t.brand %> <% end %> <% end %> </div> posts/new.html.erb <%= form_for @brand do |brand| %> <div class="field"> <%= brand.label :brand %> <%= brand.text_field :brand, :size => 10 %> </div> <%= brand.submit "追加する" %> <% end %> <%= form_for @post do |f| %> <div class="field"> <%= f.label :brand %> <%= f.collection_select(:brand_id, Brand.all, :id, :brand) %> </div> <%= f.submit "投稿する" %> <% end %> 4.ルートをかく 最後にルートを書いていきます。 routes.rb Rails.application.routes.draw do resources :posts resources :brands end 以上です!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

20代後半以上の初学者が必ずぶちあたる問題に今ある知識で立ち向かう。

プログラミング学習をしているといつか遭遇する世界のナベ○ツ問題。私は今朝でした。 中々具現化せずにスルーしていく人が多いであろうなか締切が迫っているプロジェクトを差し置いてやる。やらねばならない。 【問題】 「「3の倍数と3のつく数字のときだけアホになります」をターミナルに出力しなさい。」 【構想】 条件分岐と条件の組み合わせを利用して実装ができそうです。 範囲→メインとなる30代の数字は全部出力したいので40までとしましょう。 アホになる→リスペクトも込めて「語尾に"!!!"を付与する」あたりで手を打ちましょう。 【step1】 whileメソッドを使って指定した条件下で繰り返し処理を行うよう大枠を作成しましょう。 qiita.rb def everything_that_happens_twice_will_surely_happen_a_third_time num = 1 while num <= 40 do ここに条件を書くよ num = num + 1 end end 1から始まるようnumを定義し、whileメソッドで40以下と設定してdo~end間の処理を繰り返します。※doは省略可 num = num + 1 とすることで繰り返し処理の流れでnumを変化させます。 【step2】 3の倍数と3のつく数字のときだけアホになるを条件としてコード化します。 qiita.rb if num.to_s.include?("3") || num % 3 == 0   puts "#{num}っ!!!" else   puts num end 3の倍数に関しては%を使い3で割った際の余りが0であれば達成。 問題は3のつく数字のときを条件式に落とし込む点。私の引き出しには数値を参照するメソッドがないため、'to_s'を使ってnumを一度文字列にした上で'include?'を使って文字として"3"を参照しました。include?って数値参照できないのね! 【step3】 だいたい完成ですね。どきどきしてきました。 ただ、思い返していると度々数字を言い切った後に締めの一言を発していたような 範囲を41までにしてnum == 41のときに締める条件を足して完成させましょう。 qiita.rb def everything_that_happens_twice_will_surely_happen_a_third_time num = 1 while num <= 41 do if num.to_s.include?("3") || num % 3 == 0 puts "#{num}っ!!!" elsif num == 41 puts "ぁおもろぉーぅ!" else puts num end num = num + 1 end end できたっっっ! ターミナルで実行してみます。 楽しかったです。 メソッド名だけでも覚えて帰ってください。 以上。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】ActiveRecord の order(:count_all) とは何なのか

ActiveRecordにてGROUP BYのCOUNTを取りたいとき、他の記事を参考に以下のようなコードを書いたのですが、 Article .where(is_published: true) .group(:id) .order(:count_all) .count (例文なので全く意味のないクエリですが、本来はjoinsとか色々やって集計してます) このorder(:count_all)のcount_allがどこから来たのか分からず、調べてもわからなかったのでメモとして残しておきます。 結論 結論として、このcount_allというカラム名は、引数なしの.countを呼び出した時にASとして追加されるCOUNT(*)のエイリアス名を指定しています。 今回のクエリは最後に引数なしの.countという集計関数を呼び出していますが、これがないとorder(:count_all)は機能しません。 実際に吐かれるSQLを見た方が早そう。 SELECT COUNT(*) AS count_all, [Article].[id] AS article_id FROM [Article] WHERE [Article].[is_published] = 1 GROUP BY [Article].[id] ORDER BY [count_all] ASC このように、たんに.groupのみを行なったカラムにはASでテーブル名+カラム名が、.countを用いた場合にはcount_allというエイリアスが指定されています。 もうわかると思いますが、ちなみに.count(:id)など引数にカラムを追加した場合のエイリアス名はcount_idになります。 最後に ちゃんと理解せずにググりながらORMをガチャガチャしていたのでcount_allが何なのかよくわからずになってしまったのですが、ちゃんと吐き出されるSQLと見比べながらやったら一発でわかる疑問でした。 普通のSQLを書く時は自分でエイリアスを設定するし、感覚的にorder_byのあとにcountが来ることはないので、慣れていないと脳がバグりがちですが頑張りたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ネームエラー uninitialized constant NameError

お疲れ様です。 今日はこのエラーを解消できたので備忘録として書かせていただきます。 エラー内容 このエラーで活用させていただきました(ありがとうございます) しかしながら、、クラス名とファイル名はあってました。 原因 クラスの規則として_を使用してはいけないこと!! shipping_fee.all, クラス名として、 shipping_feeは_が使っているからクラス名として成り立たない。 解消法 ShippingFee.all, アンダーバーを使わない代わりに、 アンダーバーのあとの文字を大文字に変えます! 何時間悩んだんだろうか、、、
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

fastlaneのdeliverからAppStoreのメタデータ送信する際の留意点

概要 2021/08現在における fastlane deliver を使った AppStore へのメタデータ送信について、ドキュメントが少なかったので留意点を記しておきます。 前準備 ■ AppStre API Key 2021/08現在では deliver からメタデータをCI経由で送る場合 AppStore API Key が必要です。 これがないと 2FA をクリアできないので、、 ローカルで実行するだけであれば、fastlane で利用できる通常のログイン機構で大丈夫です。 その場合、コマンドの途中で 2FA のパスワードを求められることになります。 ちなみに.envなどを利用して環境変数に必要keyを格納し、下記のようにAPIKeyを取得できるような fastlane private action を Fastfile に作っておくと便利です。 #### App Store API への認証Key生成 desc "App Store Connect API Key" # private_lane :app_store_connect_key do lane :app_store_connect_key do api_key = app_store_connect_api_key( key_id: ENV["APP_STORE_API_KEY_ID"], issuer_id: ENV["APP_STORE_API_ISSUE_ID"], key_content: ENV["APP_STORE_API_KEY_CONTENT"], duration: 1200, in_house: false ) end #### Deliverによるメタ情報&app送信 desc "Upload with Deliver" lane :deliver_app do |options| deliver( api_key: app_store_connect_key, 〜 割愛 〜 ) end AppStoreAPIに関するドキュメント ■ AppStore に送信するメタデータ AppStoreに送信するメタデータはAppStoreConnectのGUIに沿って設定したものをダウンロードすると良いです。 メタデータ用のファイル群だけでは何が何だかわかりずらく、一つ一つゼロから構築するのは大変なので。 ダウンロードはAppStoreへのログイン機構を利用したアクションの実行が必要です。 deliver の download_metadata 関数は api_key に対応していないので。。。 したがって Appfile などにログインに必要な項目を記載して実行してください。 下記のコマンドを実行すると 2FA を介してメタデータのダウンロードが行えます。 fastlane deliver download_metadata 以下を参考に更新があれば行ってみてください。 ■ AppStore に送信するスクリーンショット 下記にまとめているので参照してみてください。 ■ レーティングに関するメタデータ deliver でのメタデータ管理を行うのであれば、レーティングに関してもデータ送信できるようにしておいた方が良いです。 この辺の変更もGithubなどでバージョン管理できると、後続の関係者に意図が伝わると思います。 レーティング情報については fastlane 経由のダウンロード方法がわからなかったので、わかり次第追記したいと思います。 直接APIから取得する方法は こちら。 差し当たり、下記の json を用意して、プロダクトにあった設定値にしてください。 { "alcoholTobaccoOrDrugUseOrReferences": "NONE", "contests": "NONE", "gamblingSimulated": "NONE", "horrorOrFearThemes": "NONE", "matureOrSuggestiveThemes": "NONE", "medicalOrTreatmentInformation": "NONE", "profanityOrCrudeHumor": "NONE", "sexualContentGraphicAndNudity": "NONE", "sexualContentOrNudity": "NONE", "violenceCartoonOrFantasy": "NONE", "violenceRealisticProlongedGraphicOrSadistic": "NONE", "violenceRealistic": "NONE", "gambling": false, "seventeenPlus": false, "unrestrictedWebAccess": false } 以前はこちらのプルリク差分のように大文字での指定になっていましたが、指定が新しくなっているので注意してください。 レーティングのKeyValueドキュメント deliverからの送信 さてでは実際に deliver を利用してデータ送信する際のパラメータ設定についてです。 下記に基本的なものを羅列しておきました。 fastlane のドキュメントサイトにデフォルト値が記載されているので、改めて指定不要なものは削除してください。 注意書きですが、バイナリの送信を行う場合、当然ですが前もって fastlane の gym などを利用したアプリ生成が必要です。 また生成されたアプリバージョンがすでに AppStore に存在する場合エラーになるので注意してください。 deliver( api_key: app_store_connect_key, # <- 前述で説明した api_key を設定 submit_for_review: true, # <- バイナリ送信時にレビューに送信するか否か skip_binary_upload: true, # <- 生成されたバイナリをアップロードするか否か force: true, # <- おそらくですが送信時に生成されるHTMLレポートの検証をスキップするか否か。基本trueで良いようです reject_if_possible: true, # <- 申請中であれば取り消して上書きするかどうか metadata_path: "fastlane/metadata", # <- metadata のフォルダ指定 skip_screenshots: false, # <- スクショのアップをスキップするかどうか screenshots_path: "fastlane/screenshots", # <- スクショのフォルダ指定 overwrite_screenshots: true, # <- スクショを上書きするか否か automatic_release: true, # <- 申請通過時の自動リリース設定 app_rating_config_path: "fastlane/app_rating_config.json", # <- レーティングのjson指定 run_precheck_before_submit: false, # <- 送信前の検証。api_keyを利用するとこけるので false submission_information: { add_id_info_uses_idfa: false, # <- 広告ID情報-idfaを使用するか否か add_id_info_serves_ads: false, # <- 広告ID情報-広告を配信するか否か add_id_info_tracks_install: false, # <- 広告ID情報-インストールの追跡を行なっているかどうか add_id_info_tracks_action: false, # <- 広告ID情報-アクションの追跡を行なっているかどうか export_compliance_encryption_updated: false # <- 暗号化について更新があるかどうか } ) deliver公式ドキュメント   【補足】プライバシー詳細情報に関するメタデータについて 現状 deliver を利用してプライバシー詳細情報に関する設定値をアップロードすることはできませんが、バージョン管理の観点からメタデータによる fastlane 経由のアップロードを行うのも良いかと思います。 以下の記事を参照してみてください。       以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on Rails】font-awesome-sassを導入してアイコンを重ねて表示する方法

対象者 RailsアプリにFont Awesome導入予定の方 Font Awesomeを重ねて表示したい方 目的 * アイコンを重ねて表示する! イメージは下記の通り 使用環境 Rails 5.2.5 注意:Rails6をご使用中の方は導入方法が異なります。詳しくはこちらを御覧ください 実際の手順と実例 1.FontAwesomeを設定する Gemfile gem 'font-awesome-sass' 導入後はbundle installを実行する 続いてapplication.cssをapplication.scssに書き換えて下記のコードを追記します。 順番を入れ替えないように注意! application.scss @import 'font-awesome-sprockets'; @import 'font-awesome'; 2.アイコンを重ねる表記方法 <div class="col-md-4"> <span class="fa-stack fa-4x"> <i class="fas fa-circle fa-stack-2x "></i> <i class="fas fas fa-search fa-stack-1x fa-inverse"></i> </span> </div> 3.解説 複数のアイコンを重ねるにはfa-stackで重ねる2つの要素の親要素として指定します。 続いてiタグで囲まれたアイコンを最背面から順に記述します。 fa-stack-2x、fa-stack-1xと指定することで、背面のアイコンの大きさが重ねるアイコンの大きさの2倍になります。 これで実装完了です! 参照 Stacked Icons (FontAwesome 公式) 【Rails】 font-awesome-sassの使い方を徹底解説!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ポートフォリオ紹介(INTELIST)【Ruby on Rails / AWS】

はじめに 業界・実務未経験者がエンジニア転職を目指して独学で約半年間プログラミング学習を行い、このたび転職用にポートフォリオを作成したため紹介していきたいと思います。 今後もアップデートをしていく予定なので、何かあれば本記事のコメント等にフィードバックをいただけますと助かります! アプリ概要 気になるものを何でもかんでもリスト化して管理・シェアするためのSNSアプリ「INTELIST(いんたりすと)」を作成しました。 気になるものをジャンル問わず投稿し、友人とシェアできる リスト化しておくことで後から確認できる 他のユーザーの興味をランキングで確認し、トレンドを把握できる といった特徴があります。 下記のURLにて公開中ですので、よろしければご覧ください! https://inte-list.com(PCでの閲覧推奨です) GitHubリポジトリ 製作背景 このご時世の中、「落ち着いたら〇〇行ってみよう」「〇〇って漫画がおすすめ」といったような会話をすることが増えたのですが、いかんせん増えすぎたせいで 「行きたいって話してたのどこだっけ…」 「勧められたのなんだっけ…」 「この話誰としたんだっけ…」 とド忘れしてしまうものが出てきました。そのような会話自体もLineやDiscordなどの様々な媒体を使用していたり、通話で話しただけだったりと後から拾いなおすのが難しく、せっかくの楽しみな情報が抜け落ちてしまうのがもったいなかったので、このド忘れを解消する方法として製作したのがINTELISTです。 記録するにあたり、飲食店、読書、音楽などに特化したサービスは比較的すぐ見つかったのですが、ざっくばらんに何でもかんでも記録&シェアするというサービスは見当たらないようだったので自分で製作してみた次第です。 アプリの機能紹介 機能一覧 # 機能名 説明 1 ユーザー機能 新規登録、登録内容変更、アバター画像設定、ログイン、ログアウト。 2 ゲストログイン機能 登録せずゲストとしてアプリを使用可能。ゲストユーザーは削除/編集不可。 3 フォロー機能     ユーザーをフォロー可能(Ajax)。原則はフォローしているユーザーのみを自身のタイムラインに表示。 4 投稿機能 投稿、編集、削除。投稿にはアイテム/コメント/参考URL/タグを登録可能。参考URLを入力した場合は外部APIを使用してリンクサムネイルを自動作成。 5 投稿へのいいね機能 投稿をいいねが可能(Ajax)。いいねした投稿をマイページで一覧表示。 6 投稿へのコメント機能 投稿へのコメント追加/削除が可能(Ajax)。コメントした投稿をマイページで一覧表示。 7 タグ付け機能 投稿へのタグ登録/編集/削除が可能。タイムライン等で表示されているタグをクリックすると、同じタグを含むアイテム一覧を表示。 8 マイアイテム機能 自分の投稿したアイテムを一覧表示。完了/未完了を登録し、ステータスで絞り込みが可能(Ajax)。 9 検索機能 ユーザー一覧、アイテム一覧、マイアイテム一覧の絞り込み検索が可能(Ajax)。 10 ランキング機能 全ユーザーorフォローのみ、期間を指定した投稿数上位10位のランキングを一覧表示。 使用イメージ(一部機能抜粋。番号は一覧のNo) 4. 投稿機能 「新規投稿」ボタンから投稿画面を開き、気になるアイテムを登録します。 (投稿画面はBootstrapのモーダル機能を利用しています。) 投稿にはアイテム名、投稿内容(コメント)、参考URL、タグ名を登録できます。 参考URLを入力した場合、投稿完了時に自動的にサムネイルを作成します。 タグはエンターを入力することでバッチ化します(tagsinputを使用)。 7. タグ付け機能 前述の通り、投稿時にはタグを登録でき、タグを利用することで似たジャンルのアイテムを探すことができます。 画面に表示されているタグバッチをクリックすると同名タグを含むアイテム一覧を表示します。 (上のgifではボドゲ→ゲームの順でタグをクリックし、絞り込みを行っています) 投稿作成時にはタグ名称でTagテーブルを検索し、同名タグがあれば既存レコードを使用、なければ新規に作成します。 8. マイアイテム機能 ヘッダー → アカウント → 「マイアイテム一覧画面」 からは、自分が登録したアイテムをリストで確認できます。 アイテムごとに完了済/未完了のステータスを設定することができ、実際に行ってみた場合などには完了済にできます。 マイアイテム一覧ではステータスごとで絞り込みを行えるため、まだ行っていないアイテムだけを確認することもできます。 9. 検索機能 ユーザー一覧/アイテム一覧/マイアイテム一覧では複数ワードによる絞り込み検索ができます。 (上のgifではアイテム一覧ページにて、タグ:ボドゲ、アイテム名:魔女、にて絞り込みを行っています。例ではあえて2ステップ踏んでいますが、もちろん1ステップでも可能です。) 検索はLike検索で、複数ワードがある場合はAND検索します。 リセットボタンを押すと検索が解除されます。 10. ランキング機能 ランキングページで他のユーザーに人気のものをチェックできます。 全ユーザー/フォローのみ、週間/月間/全期間での条件ごとで絞り込んだランキングを表示できます。 (上のgifでは「全ユーザー&週間」→「全ユーザー&月間」→「フォローのみ&月間」と切り替えています。) 使用技術/設計等 言語等 フロントエンド HTML Sass JavaScript(jQuery3.6.0) Bootstrap4.6.0 バックエンド Ruby3.0.2 Ruby on Rails 6.1.4 MySQL8.0.23 各種gem gem名 用途(記載している#は機能一覧の#を表します) devise #1のユーザー機能に使用。 carrierwavemini_magickfog-aws #1のアバター画像設定に使用。fog-awsを使用し保存先をS3バケットに設定。 httparty #4のサムネイル作成機能において、外部APIへのデータ送信およびレスポンスのHash変換に使用。 kaminari 各種ページのページネーションに使用。 counter_culture 一部モデルの件数を取得する際のN+1問題回避のため使用。 bullet N+1問題の検出に使用。 better_errorsbinding_of_caller エラー画面を見やすくするために使用 rspecfactory_bot_railsrubocop テストに使用 インフラ 本番環境 AWS(VPC、EC2、RDS、S3、Route53、ALB、ACM、IAM) Nginx1.20.0 Unicorn6.0.0 Capistrano3.16.0 CircleCI2.1 開発環境 Docker20.10.8 docker-compose1.29.2 その他のツール git2.25.1 / GitHub インフラ構成図 ローカルではWSL2とDocker、docker-composeを使用して開発しています。 ローカルで開発した内容をGitHubへpush→CircleCIで自動テスト(RuboCop&RSpec)→CapistranoでEC2上に自動デプロイという流れを経て公開しています。 ユーザーからの接続はRoute53を使用して独自ドメイン化、ALBとACMを使用して常時SSL接続を使用するよう設定しています。 EC2内ではwebサーバーにNginx、アプリケーションサーバーにUnicornを使用しています。 ユーザーのアバター画像用にS3バケットを使用しています。 投稿時のサムネイル作成用に外部サービスlinkpreviewのAPIを使用しています。 ER図 投稿時にはアイテム名を入力しますが、入力されたアイテム名でItemテーブルを検索し、同名アイテムが見つかれば既存レコードを使用、見つからなければ新規レコードを作成します。 投稿時にはタグ名を入力できますが、PostTagMapテーブルを中間テーブルとたTagテーブルを入力されたタグ名で検索し、同様に既存レコード使用or新規レコード作成を行います。 どちらのテーブルも同名のレコードが存在する場合はそれを引用、同名が見つからない場合のみ新規レコードを作成することでデータ数が無駄に増加するのを抑えています。 工夫した点 非同期通信(Ajax) 各種ページに非同期通信を採用し、リロードによるストレスを軽減するよう心がけました。 フォロー・いいね・コメントのAjax化 各種ページのタブ切替のAjax化 検索結果表示のAjax化 サムネイルの自動生成(外部API) 投稿作成時に入力した参考URLをもとに、サムネイルを自動生成する機能を実装しました。 背景として、アイテム名を見ただけでは他のユーザーが面白そうかイメージがわかないため、何か画像が欲しいと考えました。 とはいえ投稿者がいちいち画像を用意して添付するのは手間が増えすぎるため、linkpreviewという外部APIを利用しています。 このAPIでは投稿者が入力したURLをもとにサムネイル用のデータをJSONで返す機能が利用できるため、メソッドに組み込んでPostテーブルにサムネイル関連情報を保存→viewで表示できるよう実装しました。 小さな工夫として、サムネイル作成に少し時間がかかるためローディングサークルを表示して待機時間と分かるようにしました。 ランキング機能 利用者に人気のあるアイテムのトレンドが知れるようランキング機能を設けました。 タイムラインだけではフォローしている知人の興味しかわかりませんが、ランキングにより全く別傾向のものにも出会えます。 全ユーザー/フォローのみ、週間/月間/全期間での条件ごとでランキングを表示できます。 ここから気になったユーザーをフォローするなどして、面白いものをどんどん見つけられます。 今後の課題 転職活動をしつつ、下記のような改善を加えていければと考えています。 公開範囲の指定:投稿をフォロワーにのみ公開する設定 通知機能:フォロー、いいね、コメント等の通知 ソート機能:アイテムやユーザーの一覧ページにソート機能を追加(現在はID順のみ) インクリメンタルサーチ:検索結果を即時表示できるように 日程調整機能:ユーザー間で共通のものに興味を持っている際、複数ユーザー間でプライベートに日程を調整できる機能 評価機能:気になったものを実際に試した後に★などでランク付け GoogleChrome拡張機能:少し趣向が変わりますが、外部のページを開いている際にそのページ上で投稿できる拡張機能があるとものすごく便利になりそうです 感想 自分で考えたものがどんどん形になっていくため、製作していてとても面白かったです。 また、転職活動自体への有効性は別としても、ポートフォリオを作ることで自分の好きな領域や苦手な領域がだんだんわかってくるのも今後のキャリアプラン検討の糧にできそうです。 ポートフォリオ作成前の学習段階においては様々な書籍やサービス・記事を参考にさせていただきましたが、現在は独学でエンジニアを目指す方も増えているようで、ある程度学習のロードマップが確立されていることもあり助かりました。 とはいえ、勉強を一通り終えていざポートフォリオ作成!となると何から手を付けるのか分からなかったり、エラーが多発したりと苦労の連続でしたが、乗り越えた時の快感はたまらないものがありますね。 前述の本ポートフォリオの改善しかり、引き続き精進します! ここまで読んでいただきありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む