- 投稿日:2021-07-15T22:38:43+09:00
Ruby pを使ったコード検証(デバック)
pを使ったコードの検証方法 想定した処理がどこまで正しく行われているか?デバックして状況確認をする 使えそうなシーン ・ エラーが起こったとき ・ 今この変数は文字列?数値?配列? ・ ifで正しく条件分岐されてるのか? ・ 他人のコードの処理の流れを追いながら理解したい 方法 「p」を処理ごとに分かりやすく文字/数値で入れる 例① 他人のコードの処理の流れを追いながら理解したい p "a:" seats_and_groups = gets.split(/\s/) p "b:" empty_seat = [*1..(seats_and_groups[0].to_i)] p "c:" seats_count = empty_seat.count p "d:" number_of_visitors = seats_and_groups[1].to_i p "e:" [*1..number_of_visitors].each do p "f:" used_seats = gets.split(/\s/) p "g:" users = used_seats[0].to_i p "h:" seating_number = used_seats[1].to_i p "i:" fill_last_number = ((seating_number + users) - 1) 続 出力 (入力1回目[6 3]/2回目[2 3]での、実行された処理の違いが分かりやすい) "a:" 6 3 "b:" "c:" "d:" "e:" "f:" 2 3 "g:" "h:" "i:" 例② 今この変数は文字列?数値?配列? if next_seat_candidate.count == next_seat_candidate.uniq.count p "1:" p empty_seat if ((seating_number + users) - 1) > seats_count empty_seat = empty_seat - [*1..fill_last_number] empty_seat = empty_seat - [*seating_number..seats_count] else empty_seat = empty_seat - [*seating_number..fill_last_number] p "2:" p empty_seat end 出力(変数/配列の状況の変化がわかる) "1:" [1, 2, 3, 4, 5, 6] "n" "p" "2:" [1, 2, 5, 6] "f:"
- 投稿日:2021-07-15T21:36:16+09:00
2次元配列を作る際に気をつけること
今まで3*3(要素がすべて1)の二次元配列を作成する際 array.rb array = Array.new(3,Array.new(3,1)) array[2][2] = 3 p array としたら、普通はarray[2][2]の部分だけが2になって欲しいが、このコードでかくと 結果 [[1, 1, 3], [1, 1, 3], [1, 1, 3]] となってしまい思っていたのとは異なるため、この2次元配列の作り方はよろしくない mapメソッドを使用する これを防ぐために、コードを改良した array2.rb array = Array.new(3).map{Array.new(3,1)} array[2][2] = 3 p array 結果 [[1, 1, 1], [1, 1, 1], [1, 1, 3]] まとめ 最初の書き方で書くと、一見2次元配列ができている用に見えるが実際に作られているものは違うらしい。 また調べてみようと思う。
- 投稿日:2021-07-15T17:53:02+09:00
No route matches [POST] エラー解決方法 form_with namespace使用時
前提 ECサイトを作成しています。 商品登録ページで以下のようなルーティングエラーが発生しました。 今回、namespaceを使い管理者側(admin)、顧客側でルーティングをわけていました。 エラーの内容 createアクションはあるし、POSTになっている。 解決方法 <%= form_with model:@item, local:true do |f| %>を、以下の通り書き換え。 <%= form_with model:@item,url:admin_items_path,local:true do |f| %> データが、form_withの判断で/itemsに送られていました。 namespaceを使っており、本来飛ばすべき先は、admin_items_pathでした。 エラーの原因はform_with namespace使用時には注意! <%= form_with model:@item, local:true do |f| %> 商品の新規登録画面でform_withを用いてフォームを作成していました。 <%= form_with model:@item, url:'admin_items_path', local:true do |f| %> このようにフォームで入力したデータの送信先をurlで指定することもできるというのは知っていましたが、 resoucesを使用してルーティングしていたので、urlの指定は不要という認識でいました。
- 投稿日:2021-07-15T16:57:15+09:00
【個人開発】メンタルヘルス VS メンタルヘルスマネジメント!【IKEMENTAL】作成しました。
はじめに 皆さん、笑って働けていますか? 昨今、組織内のメンタルヘルスの問題は増加の一途を辿っています。 私が前職で労務を担当していた際も改善の糸口が見えず頭を悩ませていました。 ハラスメントを行ってしまった社員と被害にあった社員の言い分を聞くに、単に個人間の問題だけでなく、企業風土や社内教育、業務形態など様々な問題が絡んでいたからです。 この問題を解決するためには社員一人一人が適切な知識と指導方法、自身をストレスから守る術を身につける必要があると感じました。 そこで今回、そんな私の経験もふまえメンタルヘルスマネジメントを知り、組織全体でメンタルヘルスに立ち向かう意識を作るアプリを作成しました。 【今回作成したサービス】 https://www.ikemental.com (✴︎PC専用アプリとなっております) 【Twitterアカウント】 https://twitter.com/kosuke54177851 サービス概要 メンタルヘルスマネジメントをゲーム感覚で体感しながら出世街道を駆け上がり社長を目指す「IKEMENTAL」(イケメンタル)を作りました! アプリの構成・遊び方 1、トップページ シンプルでポップなデザインで全体を統一しました。 2、チュートリアル ログインせずに操作や機能の説明をうけることができます。 最後まで確認して是非!本編でも遊んでみてください。 3、本編 ログインするとゲームが始まります。 新入社員編から経験値とメンタル値をコントロールしながら役職を上げていきましょう! 4、遊び方 1、チュートリアルで遊び方と機能を確認 2、ユーザー作成、ログイン 3、クイズに答えて経験値を上げ、昇進を目指す!(全3ステージ) 以上!笑 あまり操作や設定に凝りすぎると操作がめんどくさくなってしまうと思いシンプルでわかりやすいアプリを目指しました! こだわった点 1、メンタルゲージと経験値ゲージ 問題をスタートするとメンタルゲージが減り、回答によって経験値が増加します。 自分の回答の選択が蓄積していく感覚が視覚的に認識できるようchart.jsとJqueryを用いて非同期で実装してみました。 コントローラー側で保存しjs側でフロントの処理を同時に行うことで誤差が生じないように実装することに苦戦しましたが上手く実装することができました。 一応、SPAを意識しましたが要所でリロードすることで差が生じないようにしています。 2、回答によって変わるキャラクターと吹き出し あなたの回答が人間の心にどういう影響を与えるかをイラストで表しました。 ゲーム性を持たせるためにわかりやすく楽しい雰囲気を目指しました。 jQueryで回答がクリックされると同時に様々な機能が同時に発火するようロジックを組みました。 当初は700行近くコードを書いていたのですがリファクタリングしてなんとか100行まで削ることができたので今後も学習を重ねながらリファクタリングに努めていこうと思います! ・ メンタルヘルスマネジメントに即した問題構成 メンタルヘルスマネジメントは大きく二つの分野で構成されます。 Self Care :自身のストレスケアLine Care :部下や組織のメンタルヘルスマネジメントを行う このアプリではこの二つの分野のクイズを解きながらクリアを目指す仕様になっています。 1、Self Care メンタルゲージが一定数以上減るとタスクが行えなくなるので回復タスクで回復します。 現実でもストレスが溜まった時は休んだり、リフレッシュしてうまく付き合っていかなくてはなりません。 このアプリでもその状況に即した実装にしました! 2、Line Care 新入社員編では簡単なマネジメントと基礎知識を解いていただきます。 役職が上がると問題の難易度や部下の教育面でのマネジメントの問題が中心に出題されます。 現在、部下を持っていない方も将来もった時のことを想像しながら解いてみましょう。 使用技術 ・ バックグランド Ruby Rails JavaScript ・ 主なgem sorcery seed-fu chart-js-rails dotenv-rails enum-help meta-tags bullet rubocop ・ テスト Rspec ・ フロントライブラリ jQuery slick.js chart.js ・ ストレージサービス ActiveStorage 今後の実装、改善したいこと ・ 改善面 chart.jsの非同期処理の改善 現在、問題を解き昇進したタイミングでモーダルが表示されるのですが、モーダルを閉じた直後に問題の続きを行うと経験値のゲージが変動しないようになっています。 ユーザーファーストで使っていて楽しいサービスを目指しているので改善し、常にゲージに反映されるよう実装しようと思っています。 ・ 実装面 SNSログイン機能 メンタルヘルスマネジメント問題の充実化 全問題の回答表示画面 終わりに 初めて個人サービスをポートフォリオとして作ってみて詰まったところや自分の知識の浅さを痛感した点など様々な発見がありました。 今後も何らかのかたちでアウトプットしていければと思います。 メンタルヘルスは社会問題であり、一長一短で解決する問題ではないですが少しでも笑って元気に働ける人が増える一助になればと思います! よかったら遊んでみてください! https://www.ikemental.com 最後まで目を通していただきありがとうございました!
- 投稿日:2021-07-15T14:12:21+09:00
ハッシュやシンボルの理解 [Rubyチェリー本 5章まとめ]
この章ではハッシュやシンボルについて開設されています。 個人的にはこの章は、特に勉強になりました。 知識が深まったと言うよりは、全然知らなかった、と言う感じです。 ポートフォリオ制作では、早く完成させることが一つの目的になっていたので、シンボルの利点の一つである応答時間の速さなど全く気にかけていませんでした。 ハッシュ ハッシュとは、キーと値の組み合わせでデータを管理するオブジェクトのことです。 他の言語では、連想配列やディクショナリ、マップなどと呼ばれている。 # 空のハッシュ {} # キーと値の組み合わせ { キー1 => 値2, キー2 => 値2, キー3 => 値3 } { 'japan'=>'yen', 'us'=>'dollar', 'india'=>'rupee' } 要素の追加・変更・取得 # 追加する場合(既にキーが存在している場合は上書きされる) ハッシュ[キー] = 値 currencies = { 'japan'=>'yen', 'us'=>'dollar', 'india'=>'rupee' } currencies['italy'] = 'euro' currencies #=> { 'japan'=>'yen', 'us'=>'dollar', 'india'=>'rupee', 'italy'=>'euro' } ======================== # ハッシュから値を取り出す ハッシュ[キー] currencies['us'] #=> 'doller' ハッシュを使った繰り返し処理 currencies = { 'japan'=>'yen', 'us'=>'dollar', 'india'=>'rupee' } # ブロック引数が2つの場合 currencies.each do |key, value| puts "#{key}は#{value}" end ========================# ブロック引数が1つの場合 currencies.each do |key_value| puts "#{key_value[0]}は#{key_value[1]}" end ======================== #=> japanはyen # usはdoller # indiaはrupee ハッシュの要素の削除 currencies = { 'japan'=>'yen', 'us'=>'dollar', 'india'=>'rupee' } # deleteメソッドで削除したい要素のキーを指定、戻り値は削除された要素の値 currencies.delete('japan') #=> 'yen' currencies = { 'us'=>'dollar', 'india'=>'rupee' } ======================== # 削除したい要素のキーがみつからない場合はnilが返る currencies.delete('italy') #=> nil currencies = { 'japan'=>'yen', 'us'=>'dollar', 'india'=>'rupee' } ======================== # ブロックを渡すとキーが見つからないときの戻り値を作成できる currencies.delete('italy') { |key| "Not found: #{key}" } #=> "Not found italy" シンボル ハッシュのキーにはシンボルが利用されることが多い。ここではその理由を説明する。ここはとても勉強になった。 シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェクトです。文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。同じ内容のシンボルはかならず同一のオブジェクトです。 シンボルはコロンに続けて任意の名前を定義する(ハッシュリテラル)。 :シンボルの名前 :apple # など シンボルと文字列の違い 1. クラスの違い。 :apple.class #=> Symbol "apple".class #=> String 2. シンボルの中身は整数として管理される 表面的には文字列ではあるが、中身は整数として管理される。 その為、2つの値が同じかどうか調べる場合は、文字列よりも高速に処理できる。 3. 同じシンボルであれば、同じオブジェクト 大量の文字列と大量のシンボルでは、シンボルの方がメモリ効率が良くなる。 # シンボルだから同じ :apple.object_id #=>1143388 :apple.object_id #=>1143388 :apple.object_id #=>1143388 # 文字列は異なるID 'apple'.object_id #=>70223819213380 'apple'.object_id #=>70223819233120 'apple'.object_id #=>70223819227780 つまりシンボルはイミュータブルオブジェクト。「何かに名前を付けたい、名前なので誰かに勝手に変更されては困る」と言う時にうってつけ。 シンボルの主な特徴まとめ 表面上は文字列っぽい →意味がわかりやすい 内部は整数 →高速に値比較できる 同じシンボルは同じオブジェクト →メモリ使用効率◎ イミュータブルオブジェクト →勝手に変更されることはない メソッドのキーワード引数とハッシュ メソッドに引数を渡す時に、それぞれの引数がどんな意味を持つのか分かりづらい時がある。 def buy_burger(menu, drink, potato) # ハンバーガーを購入 if drink # ドリンクを購入 end if potato # ポテトを購入 end end # チーズバーガーとドリンクとポテトの場合 buy_burger('cheese', true, true) # チーズバーガーとドリンクの場合 buy_burger('fish', true, false) 下記のコードだけでは、何がこのメソッドによって起きているか理解しづらい。 buy_burger('cheese', true, true) buy_burger('fish', true, false) このような場合に可読性の向上を図るのが、メソッドのキーワード引数。 def メソッド名(キーワード引数1:デフォルト値1, キーワード引数2:デフォルト値2) #メソッドの実装 end 先程のメソッドの場合には、以下のように適用することができる。 これにより引数の役割が明確になる。 def buy_burger(menu, drink: true, potato: true) : end buy_burger('cheese', drink: true, potato: true) buy_burger('fish', drink: true, potato: false) またキーワード引数のデフォルト値は省略することも可能。 ただし、この場合には呼び出し時には省略することはできない。 def buy_burger(menu, drink:, potato:) : end buy_burger('fish',potato:false) #=> ArgumentError:missingkeywords:drink **でハッシュを展開 ハッシュリテラル内で他のハッシュのキーと値を展開したい。 h = {us:'dollar',india:'rupee'} #**を付けない場合は構文エラーになる {japan:'yen',h} # =>SyntaxError:syntaxerror,unexpected'}',expecting=> # {japan:'yen',h} #変数hのキーと値を**で展開させる {japan:'yen',**h} #=> {:japan=>"yen",:us=>"dollar",:india=>"rupee"} 擬似キーワード引数 def buy_burger(menu,options={}) : end キーワード引数に対する、擬似キーワード引数の特徴 メソッドを呼び出す際に、どんなキーを渡してもエラーは発生しない。 メソッドの定義内で、ハッシュから値を取り出すコードを追加しなければいけない。 任意のキーワードを受け取りたい場合 **をつけた引数を最後に用意する。 # othersはハッシュとして渡される。 def buy_burger(menu, drink: true, potato: true, **others) : end またメソッドの呼び出し時には、「最後の引数がハッシュであれば、ハッシュリテラルの{}を省略できる。」という機能がある。
- 投稿日:2021-07-15T10:04:13+09:00
Rabbitを使ってみたメモ
? ? この記事は未完成です ? ? Rabbitを使った発表をしたので、次回のときのためのメモ。 Rabbitはなかなか上達しないので、不完全な記事でもとりあえず投稿。 Github リポジトリ 公式サイト スライドの生成 rabbit-slide new \ --id theme-benchmark-ja \ --base-name theme-benchmark \ --markup-language rd \ --name "Kouhei Sutou" \ --email kou@cozmixng.org \ --rubygems-user kou \ --tags rabbit ただし、GUIもついているので、単に rabbit-slide と打つだけでも大丈夫。 そうすると、README.md や config.yaml が生成されるので編集しておく。 マークダウンの記述 Ruby Document format での記述も可能だが、今だとほとんどのひとはMarkdownを利用すると思う。 # TITLE # FIRST SLIDE * ITEM 1 * ITEM 2 * ITEM 3 # SECOND SLIDE {:relative_height='100'} Rabbitを使った発表は、トークが中心でスライドはあくまで補助的に使うものあと思う。理想的にはラジオ番組のように言葉だけでストーリが伝わるようにして、各スライドは項目の箇条書き、もしくは画像を1枚貼り付ける程度にするのがよいだろう。 テーマ このあたりまだよくわかっていないが、テーマは にある。テーマをそのまま使いたいわけではなく、色合いなど一部変更したい場合が多いと思う。そんなときは、直接プレゼンテーションのディレクトリにコピーアンドペーストして、該当部分だけ編集すればよいようだ。 時間の指定 そのほか
- 投稿日:2021-07-15T09:50:56+09:00
作業中ブランチで間違ってpullしてしまった場合の対応
はじめに ローカルで機能開発中に、最新のリモートブランチの動作確認をしようと、git pull をしました。 しかし、develop ブランチに切り替えるのを忘れており、作業中のブランチにpullしてしまったため、pullを取り消す方法についての備忘録です。 前提 branchAで作業中 まだコミットしていないファイルがある状態でpullしてしまった 対応方法 git pull はgit fetch でリモートの最新状態のブランチを持ってきて、ローカルの現在いるブランチにマージするコマンドなので、pull してきたリモートブランチのマージを取り消しすればよいだけです。 つまりマージする前の位置にHEADを移動させればいいことになります。 1. HEADの移動履歴を確認 まずは、現在のHEADの位置を確認しましょう。 % git reflog # 現在のHEADの位置 e6ec135b (HEAD -> feature/branchA) HEAD@{0}: pull origin HEAD: Merge made by the 'recursive' strategy. # ここに戻したい eea24d80 HEAD@{1}: commit: branchA での作業内容 d4352211 (develop) HEAD@{2}: checkout: moving from develop to branchA これでマージ前のHEADの位置がHEAD@{1} で有ることがわかりました。 後はgit reset --hard を利用して、強制的にHEADを移動するだけです。 git reset --hard は、HEAD,作業ツリー、インデックスのすべてを指定したコミットに書き換えるコマンドになります。 注意点 ここで1つ注意しておくことは、現在のブランチで作業中の場合は、変更をコミットするか退避させておかないと、現在の作業内容が消えてしまうことです。 今回はgit stash を使って退避させる方法を取ります。 2. 作業中ブランチの変更を退避 現在branchAで作業中の内容を退避させます。 ※今回はまだ修正中でコミットしたくないため、この方法を適用 git stash save "コメント" -u 3. git pullの取り消し git reset --hard HEAD@{1} これで上手くHEADの位置が元に戻っていれば完了です。 さいごに 間違えてしまっても焦らずに対処できるように、これからもどんどん気づいたことをかいていきます。
- 投稿日:2021-07-15T09:41:43+09:00
【Rails】ActionController::UrlGenerationError: No route matchesが発生する原因の1つ
背景 Rspec初心者の自分がテストを書いていて「ActionController::UrlGenerationError: No route matches」というエラーに遭遇しました。これでちょっとハマってしまったので同じように悩む人がいたらと思いメモとしてまとめておきます。 原因 超初歩的なところでparamsにURLのパスパラメーターを設定していないのが原因でした。 例えばoffices/:office_id/user/:user_idのURLに設定したコントローラーアクション(show)をテストするためには以下のようにパスパラメーターをparamsに設定しないといけません。 get :show, params: { office_id: 1, user_id: 1}
- 投稿日:2021-07-15T08:37:22+09:00
【Rails】ポリモーフィック関連先の項目で検索する方法
はじめに ポリモーフィック関連先の項目の検索方法を時間をかけて調べたのですが、なかなか出てこなかったためまとめておこうかなと思います。 ポリモーフィック関連の作成方法などはやりません。 関連リンクを下記に載せておくので、必要であれば参考にしてください。。 Railsガイド - ポリモーフィック関連付け https://railsguides.jp/association_basics.html#%E3%83%9D%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91 関連性 以下のようなAnimalモデル、Pandaモデル、Catモデルの構成を作成します。 animal.rb class Animal < ApplicationRecord belongs_to :animalable, polymorphic: true end panda.rb class Panda < ApplicationRecord has_many :animal, as: :animalable, dependent: :destroy end cat.rb class Cat < ApplicationRecord has_many :animal, as: :animalable, dependent: :destroy end ポリモーフィック関連先の項目の検索方法 手順としては、以下となります。 AnimalモデルにPandaモデルをJOIN where句で検索を実行 まずは、Pandaモデルの例を見ていきます。 # join SQL join_sql = <<-"EOS" JOIN pandas ON pandas.id = animals.animalable_id AND animals.animalable_type = 'Panda' EOS animals = Animal.joins(join_sql) # search SQL animals.where("pandas.name LIKE '%ran%'") 次にCatモデルです。まぁ同じですが。。 # join SQL join_sql = <<-"EOS" JOIN cats ON cats.id = animals.animalable_id AND animals.animalable_type = 'Cat' EOS animals = Animal.joins(join_sql) # search SQL animals.where("cats.name LIKE '%dora%'") まとめ ActiveRecord を使っていろいろと試してみたのですが、期待する動作をしてくれませんでした。 力技であまり良くないんだろうなぁと思いましたが、SQLを直接書きました。 もっといいやり方をご存知の方がいれば、教えていただきたいです。 参考 Rails4: ActiveRecord polymorphicのjoins検索? https://smallmakeprgnote.wordpress.com/2014/09/11/rails4-activerecord-polymorphic%E3%81%AEjoins%E6%A4%9C%E7%B4%A2%EF%BC%9F%EF%BC%88%E3%83%A1%E3%83%A2%EF%BC%89/
- 投稿日:2021-07-15T08:12:14+09:00
[Rails]JavaScript(jQuery)でサーっとページトップに戻るボタン(FontAwesome)
ページトップ機能はいろんな実装方法があると思いますが、今回はJavaScript(jQuery)とFontAwesomeを使ったページトップへ戻るボタンの実装をしていきます。 スクロールが多いページだとページトップボタンは必須かなと考えます。 ただスマホの場合は指でスクロールが簡単にできるので、スマホのみのサービスの場合は必須とまではいかないかなと。(スマホではあまりページトップボタンクリックされてないみたいなデータがあったような、、、) 完成イメージはこちらです。(右下のボタン) 実際の動作を確認したい方は、ぼくのポートフォリオを確認してみてください。 ある程度スクロールしたら右下に出てくるので、クリックしてみてください。 サーッと1番上まで戻ります。 それではいってみましょう! 開発環境 ruby 2.6.3 Rails 5.2.6 前提 jQueryが使える状態 FontAwesomeが使える状態 手順 ページトップ機能を実装する手順は3ステップです! ビューでボタンを配置 CSSを追加 動きをつける ビューでボタンを配置 まずは、ビューにFontAwesomeを使ってボタンと要素を配置しています。 ボタンは全ビューで共通したものを使うのでapplication.html.erbのmainタグの中に記述していきます。 そのまま記述するとごちゃごちゃするので、部分テンプレート化しています。 views/layouts/_pagetop.html.erb <div class="container"> <div class="row"> <div class="col-12"> <!-- ページトップへ戻るボタン --> <p class="pagetop" style="display: none;"> <a href="#"> <!--ボタンの表示にはFontAwesomeを使用--> <i class="fas fa-chevron-up"></i> </a> </p> </div> </div> </div> <%= yield %>の下に配置 views/layouts/application.html.erb : <main> <%= yield %> <%= render 'layouts/pagetop' %> </main> : CSSを追加 CSSでは、 ①ボタンの配置場所 ②ボタンのデザイン ③FontAwesomeアイコンのデザイン に関する記述をしていきます。 assets/stylesheets/homes.scss /* ページTOPに戻る */ // ボタンの配置場所 .pagetop{ display: block; position: fixed; right: 18px; bottom: 10px; } // ボタンのデザイン .pagetop a{ display: block; font-size: 0; width: 50px; height: 50px; text-align: center; background: gray; border-radius: 50%; line-height: 50px; } // FontAwesomeアイコンのデザイン .pagetop a i{ font-size: 20px; color:#fff; line-height: 50px; } 動きをつける JavaScriptでは2種類の処理を記述します。 ①ページトップボタンの表示の処理 ②ページの1番上まで戻る処理 別々に見ていきます。 ①ページトップボタンの表示の処理 どれだけスクロールしたかによって、ボタンを表示非表示させます。 解説 // ページトップボタン表示、非表示 // Turbolinks無効化(詳しくは過去記事参照) $(document).on('turbolinks:load', function() { // 画面をスクロールを起点 $(window).scroll(function () { // ページのトップの位置をnowに代入 var now = $(window).scrollTop(); // ページトップから1000pxスクロールしたら以下を実行 if (now > 1000) { // ボタンがふわっと現れる $('.pagetop').fadeIn("slow"); } else { // ボタンがふわっと消える $('.pagetop').fadeOut('slow'); } }); }); ②ページの1番上まで戻る処理 表示されたボタンをクリックするとサーっとページの1番上まで戻っていきます。 解説 // ページトップへ戻るクリックで、スクロールして1番上に戻る // Turbolinks無効化(詳しくは過去記事参照) $(document).on('turbolinks:load', function() { $(function(){ // ボタンクリックで発火 $('.pagetop').click(function(){ // アニメーションで速さを指定してサーっとページトップまで戻ります $('body,html').animate({ scrollTop: 0},500); return false; }); }); }); Turbolinksに関する記事はこちら [Rails]リロードしないとJavaScript(jQuery)が動かない問題 最後にこの処理をまとめて記載しておきます。 assets/javascripts/application.js // ページトップボタン表示 $(document).on('turbolinks:load', function() { $(window).scroll(function () { var now = $(window).scrollTop(); if (now > 2500) { $('.pagetop').fadeIn("slow"); } else { $('.pagetop').fadeOut('slow'); } }); }); // ページトップへ戻るクリックで、スクロールして1番上に戻る $(document).on('turbolinks:load', function() { $(function(){ $('.pagetop').click(function(){ $('body,html').animate({ scrollTop: 0},500); return false; }); }); }); これで、ページトップ機能が実装できました。 まとめ ページトップ機能を実装する手順は3ステップです! ビューでボタンを配置 CSSを追加 動きをつける 今回は、かなりかんたんにページトップへ戻る機能を実装しました。 基本的なページトップ機能の実装方法が理解できたと思いますので、デザインを変更してみたり、スクロールする範囲を変えてみたり、1番上まで戻るスピードを変えてみたりと、いろいろ試してみてください。 自分で考えて試してみることで、もっと理解が深まって考えて実装できるようになるはずです! 頑張ってください! 最後まで見ていただきありがとうございました。
- 投稿日:2021-07-15T02:18:06+09:00
これから学習する言語についてまとめた
はじめに これからプログラミングを学習するにあたって、学ぶ言語について以下にまとめました。 (間違いがありましたら、ご指摘を頂けますと幸いです) HTML 言語の正式名称 ハイパーテキスト・マークアップ・ランゲージ(Hyper Text Markup Language)の略 ハイパーテキスト 文書・画像・図表・音声・動画などのリンクを貼ったり、埋め込むことができる仕組み マークアップ サイト内の文書に意味づけをしていく作業。 HTMLでは文書をタグで囲むことで意味をつけていくことで、 コンピューターが正しく認識できるようにする。 ランゲージ 言語 開発された経緯 WEBページを作成するために開発された言語である 主にどのように利用されているのか ほとんどのWEBページにおける基本的な骨組みはHTMLで構成されている メモ SEO「検索エンジン最適化(Search Engine Optimization)」を意識しタグを使うことで、 検索エンジンが、より正確に文書の中身を理解できるようになる。 CSS 言語の正式名称 カスケーティング・スタイル・シート(Cascading Style Sheets) カスケーティング カスケードとは、何段も連なった小さな滝のこと。 転じて、同じものがいくつも数珠つなぎに連結された構造や、 連鎖的あるいは段階的に物事が生じる様子を表す。 スタイルシート 構造化文書などにおける表示形式を制御する仕組み。 ・・・WEBページのデザインやレイアウトなどの見栄えを変更できる 開発された経緯 WEBページの見た目の部分を編集するために開発された 主にどのように利用されているのか 文字のサイズや色、レイアウトなどのWEBページ上で表現される部分を 細かく編集する際に用いられる。 メモ HTMLとセットで使用されることが多い。 HTMLは「ページの構造」cssは「ページの装飾」を指定する言語といえる。 JavaScript(JS) 言語の正式名称 ジャバスクリプト(JavaScript ) 開発された経緯 元々はWEBページに動作をつけるために開発された 主にどのように利用されているのか ・ポップアップウィンドウを出現させる ・ブラウザ上で画像を拡大表示してWebページを見やすくする ・メッセージ送付フォームやパスワードの入力フォームなどを設置する 等 メモ クライアントサイドの言語である。(反対=サーバーサイド言語) プログラミング言語のJAVAとは、全くの別物。メロンとメロンパンくらいの違う。 Ruby 言語の正式名称 ルビー(Ruby) 開発された経緯 まつもとひろゆき氏により開発されたオブジェクト指向言語・スクリプト言語である。 全てのデータがオブジェクトとして扱う純粋なオブジェクト指向スクリプト言語であり 可読性を重視した構文が特徴。 主にどのように利用されているのか Ruby on Railsというフレームワークを使うことで 効率よくWEBサイトやWEBベースの業務システムを開発することができる メモ フリーソフトウェアであるため、無料で利用でき、コピー・変更・再配布が自由である。 Ruby on Rails 言語の正式名称 ルビー・オン・レールズ 開発された経緯 Rubyを使用したフレームワークの一つ。 Rubyを使って簡単なコードでWEBアプリケーションの開発ができるように作られた 主にどのように利用されているのか クックパッド(お料理レシピサイト) グノシー(ニュースアプリ) 食べログ(グルメサイト) 等 メモ Ruby on RailsはMVCアーキテクチャ(アーキテクチャ=構造)で構成されており Model(データを扱う箇所) View(ユーザーが直接目にする箇所) Controller(ModelとViewの連携を行う箇所)の要素に分解し、開発を行う。 調べていて気になった単語 クライアントサイドとサーバーサイド ・クライアントサイド言語 (JavaScript・CSSなど) WEBサーバーから結果がプラウザに返ってきて プラウザ側で処理するときに動作する言語 ・サーバーサイド言語 (Ruby・PHPなど) サーバー内部で動く言語でデータベースの処理を行う仕組みを作る言語 コンパイラ言語とインタプリンタ型言語 前提として ・プログラムを実行するには、 機械で理解するように言語を翻訳(コンパイル)する必要がある ・翻訳の方法の違いにより呼び方が異なる ・コンパイラ言語 記述したプログラムをコンピューターが理解可能な形式に事前に一括でコンパイルする言語 ・インタプリンタ型言語 記述したプログラムを1行ずつコンパイルする言語 *気をつける点 インタプリンタ型言語≠スクリプト言語 スクリプト型言語とは 開発で使用されるコードの内、読みやすく簡易的に記述できるプログラミング言語の汎称
- 投稿日:2021-07-15T00:55:30+09:00
【Rails】新規投稿時に複数のタグ付け機能を実装したい
概要 新規投稿(photo)に複数タグ(tags)を付けられるように実装していきます。 ※タグは別途、ユーザーによる新規登録機能が実装済みとして考えます。 解決方法 ①中間テーブル(photo_tags)を生成して、各テーブルとのアソシエーションを記述する。 ②複数のタグ選択時にプルダウンのデザインを良くするためにselect2を導入する。 ③新規投稿時にタグが紐づくように、photosコントローラー内のパラメーターの記述を編集する。 ④タグの複数選択ができるように、ビューファイルを編集する。 ※前提として、すでにusersテーブルとphotosテーブル、tagsテーブルの生成が完了しているとします。 それぞれのテーブルのカラムとアソシエションは下記の通りです。 README ### users table | Column | Type | Options | | ------------ | --------------| ----------- | | first_name | string | null: false | | last_name | string | null: false | | nickname | string | null: false | | email | string | null: false | | password | string | null: false | | introduction | string | | | profile_image | ActiveStorage | | ### Association - has_many :photos ### photos table | Column | Type | Options | | ----------- | ------------- | ------------------------------ | | snap | ActiveStorage | null: false | | title | string | null: false | | description | string | null: false | | price_id | integer | null: false | | user_id | references | null: false, foreign_key: true | ### Association - belongs_to :user ### tags table | Column | Type | Options | | ------ | ------- | ----------- | | name | integer | null: false | 中間テーブル(photo_tags)を生成して、各テーブルとのアソシエーションを記述する まず、ターミナルで下記コマンドを実行します。 terminal $rails g model photo_tag マイグレーションファイルを下記のように編集します。 20210604172740_create_photo_tags.rb class CreatePhotoTags < ActiveRecord::Migration[6.0] def change create_table :photo_tags do |t| t.references :photo, foreign_key: true t.references :tag, foreign_key: true t.timestamps end end end マイグレーションファイルを編集したら、下記コマンドを実行します。 terminal $rails db:migrate $rails s #サーバー再起動 各モデルに対して、アソシエーションを記述します。 app/models/photo.rb class Photo < ApplicationRecord --中略-- has_many :photo_tags, dependent: :destroy has_many :tags, through: :photo_tags --中略-- end app/models/tag.rb class Tag < ApplicationRecord has_many :photo_tags, dependent: :destroy has_many :photos, through: :photo_tags --中略-- end app/photo_tag.rb class PhotoTag < ApplicationRecord belongs_to :photo belongs_to :tag end dependent: :destroy それぞれphoto、tagが削除されるとphoto_tagsテーブルのレコードも削除されます。 through: :photo_tags 中間テーブルを介して、多対多のアソシエーションを記述しています。 複数のタグ選択ができるように、select2を導入する 複数タグ選択が可能なプラグイン”select2”をCDN経由で導入します。 https://select2.org/getting-started/installation リンクからコードをコピペして、下記ファイルを編集します。 app/views/layouts/application.html.erb <!DOCTYPE html> <html> <head> --中略-- <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" /> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function() { $('.js-example-basic-multiple').select2(); }); </script> </head> <body> <%= yield %> </body> </html> 新規投稿時にタグが紐づくように、photosコントローラー内のパラメーターの記述を編集する。 photosコントローラーを下記のように記述します。 app/controllers/photos_controller.rb class PhotosController < ApplicationController before_action :authenticate_user!, except: [:index, :show] before_action :set_photo, only: [:show, :edit, :update, :destroy] before_action :set_tags, only: :index before_action :move_to_index, only: [:edit, :update, :destroy] --中略-- def new @photo = Photo.new @photo.photo_tags.build end def create @photo = Photo.new(photo_params) if @photo.valid? @photo.save redirect_to root_path else render :new end end --中略-- private def photo_params params.require(:photo).permit(:snap, :title, :gender_id, :price_id, :description, { tag_ids: [] }).merge(user_id: current_user.id) end --中略-- end @photo.photo_tags.build newアクション内に photoに紐づく中間テーブルのインスタンスが生成されます。 def photo_params params.require(:photo).permit(:snap, :title, :gender_id, :price_id, :description, { tag_ids: [] }).merge(user_id: current_user.id) end その後createアクションのストロングパラメーターで tag_idsを受け取って登録処理が行われるようにします。 タグの複数選択ができるように、ビューファイルを編集する collection_select文を使用して下記のように記述します。 app/views/photos/new.html.erb <%= form_with model: @photo, url: photos_path, local: true do |f| %> --中略-- <div class="form-group"> <%= f.label :names, "タグ" %> <%= f.collection_select(:tag_ids, Tag.all, :id, :name, {}, {class:"form-control js-example-basic-multiple",multiple: true, include_hidden: false}) %> </div> --中略-- <% end %> f.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, { オプション }, { htmlオプション }) multiple: true htmlオプションに記述することで、複数選択できるようになリます。 参考
- 投稿日:2021-07-15T00:34:09+09:00
with_optionsで共通のバリデーションをまとめよう!
with_options 「with_options 〇〇 」と書くことで、 複数の情報に対して共通したオプションを付けることが可能となる 記述例 「nickname, last_name, first_name それぞれのカラムが空だと保存できない」というバリデーションを設定する場合 class User < ApplicationRecord validates :nickname, presence: true validates :last_name, presence: true validates :first_name, presence: true end 上記のようにカラムひとつひとつにpresence: true(カラムが空だと保存できない)というバリデーションを記述することになる with_options使用した場合 class User < ApplicationRecord with_options presence: true do validates :nickname validates :last_name validates :first_name end end with_options presence:true do 〜 endの記述により、do 〜 endの情報に対して、値が存在 presence しなければならないという制限を一括で設けることができました。