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

Rails6 画像のプレビュー機能 + バリデーション失敗時での画像表示

実装内容 carrierwaveを使用して画像アップロード機能を実装し、「よし!これで画像の投稿機能の完成だ!!」と思っていたのですが、何か物足りなさを感じて画像投稿機能に関する記事をいろいろと調べていた所、プレビュー機能というワクワク機能に出会ったので今回はその紹介 + バリデーション失敗時でも画像を表示する方法も紹介しております。 処理全体の流れ プレビュー機能の実装 バリデーション失敗時の画像表示方法 完成形はこちら プレビュー機能 バリデーション失敗時 環境 macOS Big Sur 11.2.3 ruby: 2.7.2 rails: 6.1.3 jQuery テンプレートエンジン: slim レイアウト: bootstrap4 前提 jquery,deviseの導入は省いております。 carrierwaveの導入と実装は省いております。 viewファイル ※Rail6ではform_forは非推奨ではありますが、上記に示した環境では問題なく動作しております。 app/views/devise/registrations/edit.html.slim = form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| = render 'layouts/error_messages', model: f.object ・ ・ ・ .form-group .d-block = f.label :profile_image - if f.object.profile_image? = image_tag f.object.profile_image.to_s, id: 'profile_img_prev', class: 'user-information__img' .form-group.mt-2 = f.check_box :remove_profile_image, class: 'mr-2' = f.label :remove_profile_image = f.hidden_field :profile_image_cache - else div = image_tag 'no_profile_img.png', id: 'profile_img_prev', class: 'user-information__img' = f.hidden_field :profile_image_cache br label.upload-btn = 'ファイルを選択' = f.file_field :profile_image, id: 'file_btn' jQueryの操作ではid属性を使ってセレクタの指定を行なっていきます。 今回は、画像を表示するimage_tagにid: 'profile_img_prev'を付与し、ファイル選択ボタンにid: 'file_btn'を付与しています。 プレビュー機能の実装 webAPIのFileReaderというものを扱っています。 こちらを使うことで画像を非同期で読み取ることができます。 app/javascript/packs/application.js require("shared/image_preview"); app/javascript/shared/image_preview.js $(function () { $('#file_btn').on('change', function (e) { var reader = new FileReader(); reader.onload = function (e) { $('#profile_img_prev').attr('src', e.target.result); } reader.readAsDataURL(e.target.files[0]); }); }); それでは順を追って説明いたします。 app/javascript/shared/image_preview.js $('#file_btn').on('change', function (e) { 上記コードは、id:file_btnを付与したファイル選択ボタンが押され、画像が選択されるとイベントが発生し、スコープ内の処理内容を実行してくれます。 (e)はイベントオブジェクトのことで、発生したイベントに関する様々な情報(データ)が入っており、今回の場合、#file_btnのデータが入っています。 app/javascript/shared/image_preview.js var reader = new FileReader(); // FileReaderオブジェクトの生成 reader.onload = function (e) { $('#profile_img_prev').attr('src', e.target.result); } 次に、処理内容について説明します。 上記では、FileReaderオブジェクトを生成し、この後に説明するreadAsDataURLで画像の読み込みが完了したらreader.onloadでイベントが発生し、スコープ内の$('#profile_img_prev').attr('src', e.target.result);が実行され、該当idを付与したimage_tagのsrc値に先ほど取得した画像データを反映させています。 app/javascript/shared/image_preview.js reader.readAsDataURL(e.target.files[0]); 最後に、先ほどの説明でも登場したreadAsDataURLで指定したFileオブジェクトを読み込んでいます。 また、ファイルを配列(複数)で受け取るようになっているため、最初のファイルのみ取得するようfiles[0]としています。 ここで読み込むが完了すると、先ほどのonloadメソッドが実行され、非同期で画像が表示されるようになります。 以上でプレビュー機能の完成です! バリデーションエラー時の画像の保持方法 ここでは、キャッシュ機能を使用してバリデーションの失敗時でもアップロードした画像ファイルのデータをもとに画像を表示する方法を説明しています。 app/views/devise/registrations/edit.html.slim - if f.object.profile_image? = image_tag f.object.profile_image.to_s, id: 'profile_img_prev', class: 'user-information__img' .form-group.mt-2 = f.check_box :remove_profile_image, class: 'mr-2' # 削除機能 = f.label :remove_profile_image # ラベル = f.hidden_field :profile_image_cache # キャッシュ機能 キャッシュ機能を使用するためには下記の2点を記述する必要があります! 「(カラム名)_cache」という名前のhidden_fieldの追加 ストロングパラメーターに「(カラム名)_cache」の記述 そうすることで、f.object.profile_image.to_sでアップロードした画像ファイルのデータを取得することができ、バリデーション失敗時でも画像を表示することができます。 最後に 今回プレビュー機能を実装してみての感想ですが、「javascript、、ムズい」です笑 でも記事にすることで再度実装内容を見直すことで多少は理解できたのかなと感じています! 今後も色んなことに挑戦しながら知識を付けていきたいと思います。 間違っている箇所や分かりづらい箇所が多々あるかと思います。 その際は、気軽にコメントいただけれると幸いです。 最後までご覧いただき、ありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby でヒアドキュメント内で条件分岐やループ処理を行う方法

はじめに 複数行に渡る文字列を生成したいとき、ヒアドキュメントは便利だが、ヒアドキュメント内で条件分岐やループ処理を行う際に少し苦労したのでまとめておく。 実装方法 例として、以下のような仕様のコマンドラインスクリプトを実装してみる。 マークダウンで記述されるブログ記事に、自動で YAML ヘッダをつける機能を持つ 引数としてタイトルやサムネイル画像、タグを与えると、@options 変数で各引数の値を取得できる その際の、YAML ヘッダをヒアドキュメントで記述する。 require 'erb' header = <<~'HEADER' --- layout: post title: "<%= @options[:title] %>" image: "<%= @options[:image] %>" date: "<%= Time.now.strftime('%Y-%m-%d') %>" tags: <%- @options[:tags]&.each do |tag| -%> - <%= tag %> <%- end -%> --- HEADER puts ERB.new(header, nil, '-').result(binding) \n を実際の改行に変換した結果は以下のように出力される。 --- layout: post title: "Hello world!" image: "/images/2021/09/hello_world.png" date: "2021-09-06 22:37:34" tags: - greeting - first-post --- 解説 ヒアドキュメント内で条件分岐やループ処理を行いたい場合は ERB を使用する。 <%- と -%> で囲まれた箇所で Ruby が実行される <%= と %> で囲まれた箇所は Ruby が実行された際の戻り値が出力される 上記 2 つのどちらも、囲まれた箇所で Ruby が実行されるが、違いとしては出力結果がそのまま表示されるかされないかだ。 @options[:tags]&.each do |tag| や end の部分は、結果を出力するわけではなく、単に Ruby を実行してほしいだけなので <%- と -%> で囲む。 trim_mode について なお、<%- と -%> の記法は ERB のインスタンスを生成する際の第 3 引数に '-' を指定することで使用可能となる。これは trim_mode と呼ばれる。 # 第 3 引数に '-' を指定 ERB.new(header, nil, '-').result(binding) trim_mode を使わずに、ヒアドキュメントの出力のみを引数に指定するならば、以下のように記述することもできる。 require 'erb' erb = ERB.new <<~'HEADER' --- layout: post title: "<%= @options[:title] %>" image: "<%= @options[:image] %>" date: "<%= Time.now.strftime('%Y-%m-%d') %>" tags: <% @options[:tags]&.each do |tag| %> - <%= tag %> <% end %> --- HEADER puts erb.result(binding) ERB インスタンス生成時の第 1 引数に直接ヒアドキュメントを渡す書き方だ。trim_mode を用いないので <%- と -%> ではなく <% と %> を使用している。 この場合、出力が以下のようになる。 --- layout: post title: "Hello world!" image: "/images/2021/09/hello_world.png" date: "2021-09-06 22:43:28" tags: - greeting - first-post --- 余計な空行が出力されてしまっている。これは <% @options[:tags]&.each do |tag| %> の部分と <% end %> の部分が、行としては存在しているが、何も出力されないためである。 このように、ただ Ruby のコードを実行させたいだけの行でも、存在している以上は出力結果に反映されてしまう。 これを解決するのが trim_mode である。今回の例では第 3 引数に - を指定したので <% と %> の代わりに <%- と -%> を使うことで、余計な改行が入らなくなる。 trim_mode についての詳細は ERB のリファレンスマニュアル を参照すること。 弱点 ERB を使用するとヒアドキュメント内で条件分岐やループ処理を行うことができるが、以下のデメリットがある。 シンタックスエラーが発生した際に、行数が若干わかりづらい ERB を用いたヒアドキュメント内でシンタックスエラーが発生すると、そのエラーが発生した箇所が、ヒアドキュメント内の行数で表示される。ファイルの行数ではない。 そのため、ぱっと見で何行目にシンタックスエラーがあるのかがわからない。あまりヒアドキュメントが長くなりすぎると、シンタックスエラーが発生した際の追跡が難しくなる点に注意すること。 参考 While loop in a here documents class ERB
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby]Integer#downto

はじめに 最近コメントいただいた中で新しいメソッドを教えて頂いたので忘れないうちに記事にしておきます。 Integer#downto integer型の数字に使えます。 使用した数字から1ずつ減らした数を一つずつブロック変数に入れて繰り返し処理をします。 引数にどこまで減らすか、最小の数字を渡すことで、最小値を指定できます。 6.downto(0) do |i| print i end => 6543210 6.downto(1) do |i| print i end =>654321 6.downto(3) do |i| print i end =>6543 参考記事では下記のような使い方もしていました。 そのまま引用します↓ 5.downto(1) {|i| print i, " " } # => 5 4 3 2 1 参考: https://docs.ruby-lang.org/ja/latest/method/Integer/i/downto.html
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby クラスとインスタンスと初期化について

クラスとインスタンスとは クラスとは設計書みたいなものです。 インスタンスとは設計書を下に作られたものです。 ⚫︎具体的に説明すると クラスを野球のグローブだとします。 インスタンスが赤いグローブ、黒いグローブ、黄色いグローブ とします。 これはグローブという設計図(クラス)から いろいろな色のグローブ(インスタンス)を作るということです。 クラスについて 今回は野球のグローブをクラスとして扱っていきます。 class Glove end #Gloveクラスのインスタンス作成 Glove.new ちなみにクラス名の最初の文字は大文字(CamelCase)です。 メソッドを入れると class Glove #クラスを定義 def player pitcher = "ピッチャー" puts pitcher end end #Gloveクラスのインスタンス作成 glove = Glove.new glove.player で実行すると ピッチャー と出力されます。 インスタンス変数とローカル変数 ⚫︎インスタンス変数とは@をつけてクラス内のインスタンスで使いまわせる変数です。 ⚫︎ローカル変数とは何もつけず、使用範囲が狭い変数です。 まずインスタンス変数を使います。 class Glove #クラスを定義 def player(pitcher) @pitcher = pitcher #インスタンス変数@pitcherを宣言 puts @pitcher      end def pitcher @pitcher #違うインスタンスメソッドで呼び出す。 end end #Gloveクラスのインスタンス作成 glove1 = Glove.new glove2 = Glove.new #この2つは別々のもの glove1.player("ピッチャー") glove2.player("投手") #@pitcherのインスタンス変数で使い回せている puts glove1.pitcher puts glove2.pitcher で実行すると ピッチャー 投手 と出力 次にローカル変数を使います。 class Glove #クラスを定義 def player(pitcher) pitcher = pitcher #インスタンス変数@pitcherを宣言 puts pitcher      end def pitcher pitcher #違うインスタンスメソッドで呼び出す。 end end #Gloveクラスのインスタンス作成 glove1 = Glove.new glove2 = Glove.new #この2つは別々のもの glove1.player("ピッチャー") glove2.player("投手") #@pitcherのインスタンス変数で使い回せている puts glove1.pitcher puts glove2.pitcher で実行すると undefined local variable or method `pitcher  ' for #<Glove:0x00007f8826149ac8> (NameError) Did you mean? pitcher のようなエラーが出ます。 これはpitcherメソッドのローカル変数pitcherが呼び出されていないというエラーが出ています。 初期処理initialize Initializeメソッドはクラスがnewされた時に呼び出されるものです。 classの初期化に使われます。 使い方は class Glove def initialize() end end コードを書いていくと class Glove def initialize(pitcher) puts "投手" @pitcher = pitcher end def position puts "私のポジションは#{@pitcher}です。" end end pitcher = Glove.new("ピッチャー") puts pitcher.position で実行すると 投手 私のポジションはピッチャーです。 と出力されます。 ⚫︎参考資料 https://pikawaka.com/ruby/instance https://pikawaka.com/ruby/class https://qiita.com/ksk_lack/items/734b4961e9e6c7480d33 https://qiita.com/tomokichi_ruby/items/a2548176d85457f622a4 https://techacademy.jp/magazine/21525
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

二桁以上の整数を入力すると、十の位と一の位の数字の足し算、十の位と一の位の数字の掛け算をそれぞれ行い、最後に2つの結果を足し合わせて出力するプログラムの作成

初投稿。 とある日に遭遇したRuby問題。 ポイントは整数の十の位・一の位を個別の整数として出力するメソッドを理解すること。特に十の位! 模範解答だけではイマイチしっくり来なかったため、解答コードを元に解説を備忘録として。 〜今回はヒントがありました。〜 「入力された2桁以上の整数を10で割った計算結果の余りが1の位、整数を10で割ったものを更に10で割った計算結果の余りが10の位となります。」 現代文の問題かのようなヒントが記載されていましたが、要は'%'を使いなさいということですね。 def addition(a, b) a + b end def multiplication(a,b) a * b end def slice_num(num) # 10の位 tens_place = (num / 10) % 10 # 1の位 ones_place = num % 10 return tens_place, ones_place end puts "二桁の整数を入力してください" input = gets.to_i X, Y = slice_num(input) add_result = addition(X, Y) multiple_result = multiplication(X, Y) puts "足し算結果と掛け算結果の合計値は#{add_result + multiple_result}です" 解いていく前に忘れてはいけない大前提のおさらい! 「Rubyの性質上、整数同士(integer型)の計算だと返り値は整数になるので、小数点以下は切り捨てられる。」 この前提で今回のアプトプットの8割完了です。 では実際に2桁の整数を入力して考えてみます。 qiita.rb input = 55 の場合 slice_numメソッドに代入され、 tens_place = (55 / 10) % 10 ones_place = 55 % 10 ここで文系の私は壁にぶつかるわけです。 ones_plase = 55 % 10 すると余りは5。なるほどどんな整数が入力されても一の位は求められるわこれで。 では十の位tens_place = (55 / 10) % 10 するとそもそも5(小数点以下切り捨て)をさらに10で割って余りってなんぞ?!と。 原因は'%'の理解不足でした。 割り算では5を10で割ると0.5ですが、'%'←で割って余りを求める際の考え方は「5(10未満の数字)を10で割ると、割れない。なので5がそのまま余る」という解釈なのです。 ターミナルで実行結果を確認すると、下記の通り55でも75でも十の位が個別の整数として返ってきます。 irb(main):001:0> num = (55 / 10) % 10 => 5 irb(main):002:0> num = (75 / 10) % 10 => 7 irb(main):003:0> 2桁の整数では(num / 10)の段階で十の位を求められそうな雰囲気もありますが、ここでの '/ 10'の役割はnumの十の位を1桁目に持ってくることです。その上でnum十の位より上の数字を'% 10'で排除します。 (num / 10)では3桁以上の整数が入力された場合に対応できません。ターミナルで実行結果を確認すると、 irb(main):001:0> num = (1525 / 10) => 152 irb(main):002:0> num = (1525 / 10) % 10 => 2 irb(main):003:0> となり、'% 10'を記述することで何桁の整数でも十の位を個別の整数として求めることができます。 以上。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac】Docker+rails6+postgreSQLでの環境構築完全版

環境 MacOS Big Sur 11.5.2 ruby 3.0.2 rails 6.1.4 Docker 20.10.8 postgreSQL 13.4 ディレクトリ myapp 全て現時点(2021/09/06)での最新バージョンです。 1.用意するファイル ・Dockerfile ・Gemfile ・Gemfile.lock ・entrypoint.sh ・docker-compose.yml Dockerfile FROM ruby:3.0.2 # yarnパッケージ管理ツールをインストール RUN apt-get update && apt-get install -y curl apt-transport-https wget && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && apt-get install -y yarn RUN apt-get update -qq && apt-get install -y nodejs postgresql-client RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"] ここでyarnをインストールしておくのがポイントです。しないと後でwebpackerがインストールできずエラーになります。 Gemfile source 'https://rubygems.org' gem 'rails', '~>6' Gemfile.lockは空のままで大丈夫です entrypoint.sh #!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@" docker-compose.yml version: '3' services: db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD=password web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp ports: - "3000:3000" depends_on: - db 2.実行 $ docker-compose run web rails new . --force --no-deps --database=postgresql ↓ $ docker-compose build ここでdatabase.ymlを編集します config/database.yml default: &default adapter: postgresql encoding: unicode host: db username: postgres password: password pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default database: app_development test: <<: *default database: app_test production: <<: *default database: app_production username: app password: <%= ENV['APP_DATABASE_PASSWORD'] %> パスワードなど設定した後データベースと接続します。 $ docker-compose run web rake db:create ↓ $ docker-compose up 終わったらlocalhost:3000とネットで検索すればこの画面が出てきます。 そしたら環境構築成功です! おわりに 【Mac】Docker+rails6+MySQLでの環境構築完全版 MySQLバージョンも作ったのでぜひ参考にしてください!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac】Docker+rails6+MySQLでの環境構築完全版

環境 MacOS Big Sur 11.5.2 ruby 3.0.2 rails 6.1.4 Docker 20.10.8 MySQL 8.0.23 ディレクトリ myapp 全て現時点(2021/09/06)での最新バージョンです。 1.用意するファイル ・Dockerfile ・Gemfile ・Gemfile.lock ・entrypoint.sh ・docker-compose.yml Dockerfile FROM ruby:3.0.2 RUN apt-get update -qq && apt-get install -y nodejs # yarnパッケージ管理ツールをインストール # https://classic.yarnpkg.com/en/docs/install/#debian-stable RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install yarn WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"] ここでyarnをインストールしておくのがポイントです。しないと後でwebpackerがインストールできずエラーになります。 Gemfile source 'https://rubygems.org' gem 'rails', '~>6' Gemfile.lockは空のままで大丈夫です entrypoint.sh #!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@" docker-compose.yml version: "3" services: db: image: mysql:8.0 command: mysqld --default-authentication-plugin=mysql_native_password environment: MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: password ports: - 3306:3306 volumes: - ./tmp/db:/var/lib/mysql web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" environment: MYSQL_HOST: db volumes: - .:/myapp ports: - "3000:3000" depends_on: - db 2.実行 $ docker-compose run web rails new . --force --no-deps --database=mysql ↓ $ docker-compose build ↓ ここでdatabase.ymlを編集します config/database.yml default: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: <%= ENV.fetch("MYSQL_ROOT_PASSWORD", "root") %> host: db development: <<: *default database: myapp_development test: <<: *default database: myapp_test production: <<: *default database: myapp_production username: myapp password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %> パスワードなど設定した後データベースと接続します。 $ docker-compose run web rake db:create ↓ $ docker-compose up 終わったらlocalhost:3000とネットで検索すればこの画面が出てきます。 そしたら環境構築成功です! おわりに 未経験でしかも初心者なのでかなり苦労しましたが必要な情報は以上だけでした 一人でも多くの方の役に立てば嬉しいです 【Mac】Docker+rails6+postgreSQLでの環境構築完全版 PostgreSQLバージョンも作ったのでよかったら参考にしてください!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Example title

Example
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsの仕組みについて

1.はじめに プログラミングスクールでRuby on Railsの勉強を始めるにあたって、 Railsの仕組みを調査する機会があったのでまとめました。 2.Railsとは Rubyプログラミング言語で書かれたフレームワーク。 Railsの2つの基本理念 同じことを繰り返すな(Don't Repeat Yourself: DRY) → コードの繰り返しを避ける 保守性と拡張性を確保し、バグが減少する。 設定より規約(Convention over Configuration: CoC) → 各種設定に対してデフォルト値を予め設定 設定ファイルの設定作業を行う負担が減少。 3.MVCとは RailsはMVCと呼ばれる3機能からなるソフトウェアアーキテクチャに基づいて構成されている。 Model(モデル)  データの処理を行う機能。 データベースの入出力や、計算を行う。 View(ビュー) ブラウザへの表示に関する機能。 HTMLによるインターフェースの表示を行う。 (erbはHTML内にRubyスクリプトを埋め込むためのライブラリ。) Controller(コントローラ) ユーザからの入力をModelやViewに伝える機能。 Viewによって表示されたUIからの入力に応じて、対応するメソッドを呼ぶ。 ルーティング リクエストURLと処理を結びつける仕組み。 MVCの流れ 1.ユーザがWebページに入力を行う。 2.Controllerがユーザのアクションに応じてModelのメソッドを呼び、データの処理が行われる。 3.データがModelからControllerを経由してViewに伝達される。 4.ViewはHTMLを生成し、Controllerを経由してWebページに表示する。 (出典:MVCの仕組みについて - https://qiita.com/wacker8818/items/7c66fb9db7a2b110cb6c) 5.参考 Railsドキュメント - https://railsdoc.com/ Railsガイド - https://railsguides.jp/getting_started.html
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac】Docker+rails6+MySQLで環境構築中にaddress already in useと出たら?

環境 ・macOS Big Sur バーション11.5.2 ・シェル zsh ・Ruby 3.0.2 ・rails 6.1.4 ・My SQL 8.0.23 ・Docker 20.10.8 Docker file Dockerfile FROM ruby:3.0.2 RUN apt-get update -qq && apt-get install -y nodejs # yarnパッケージ管理ツールをインストール # https://classic.yarnpkg.com/en/docs/install/#debian-stable RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update && apt-get install yarn WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"] docker-compose.yml docker-compose.yml version: "3" services: db: image: mysql:8.0.26 command: mysqld --default-authentication-plugin=mysql_native_password environment: MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: password ports: - 3306:3306 volumes: - ./tmp/db:/var/lib/mysql web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" environment: MYSQL_HOST: db volumes: - .:/myapp ports: - "3000:3000" depends_on: - db エラー内容 $ docker compose up ↓ Starting mysql_db_1 ... error ERROR: for mysql_db_1 Cannot start service db: Ports are not available: listen tcp 0.0.0.0:3306: bind: address already in use ERROR: for db Cannot start service db: Ports are not available: listen tcp 0.0.0.0:3306: bind: address already in use ERROR: Encountered errors while bringing up the project. 【Docker】Rails+MySQLの環境をDockerで構築中「ポートの衝突」に遭遇してから解決するまで こちらの記事を参考に2つの解決策を試してみるも解決できず、、、 エラーにはaddress already in useとあるので他にaddressが使われていないか調べていきます。 $ lsof -i:3306 ↓ COMMAND PID USER ... mysqld 117 SAKAE ... 出てきました!これを消せばいいわけです! 消すコマンドはこちら $ kill 117 それでもうまくいかない場合 探すとき $ sudo lsof -i:3306 or $ sudo lsof -i -P | grep "LISTEN" 消したい時 $ sudo kill <killしたいportのPID> それでもダメなら docker-compose.yaml ports: - "3306:3306" ↓ ports: - "3307:3306" このようにポート番号を変えることで解決できる場合もあります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ratyを使ったレビュー機能 バリデーションエラーの表示方法

実装内容 Bootstrap4では、サーバーサイドでチェックした入力エラーのメッセージを表示するための「invalid-feedback」クラスが用意されており、項目ごとに分かりやすく表示されるようになっています。 しかし、入力欄に<input>タグを使用していない場合、このエラーメッセージは表示されません、、(自分の場合、Ratyを使ったレビュー機能で起こりました、、) この問題に遭遇し参考記事を探してみたのですが、該当する記事を見つけることができなかったこともあり、備忘録も兼ねて紹介しています。 処理全体の流れ 三項演算子を使用して適切なクラスの付与 styleの修正 エラーメッセージ表示用のdivタグ作成 完成形はこちら Before After 入力後 環境 macOS Big Sur 11.2.3 ruby: 2.7.2 rails: 6.1.3 jQuery テンプレートエンジン: slim レイアウト: bootstrap4 前提 gem bootstrap4 と Ratyの導入は省いております 修正前のviewファイル まず、修正前のコードを御覧ください。 app/views/travel_records/new.html.slim = simple_form_for @travel_record do |f| = render 'layouts/error_messages', model: f.object ・ ・ ・   #star   = f.label :'オススメ度【必須】', required: false   .d-flex   = f.hidden_field :review, id: :review_star   = render 'shared/star' レビュー機能のため、 カラム名をreviewとしています。 Ratyの動作に必要なjsコードはパーシャル化し、= render 'shared/star'で呼び出しています。 また、バリデーションはvalidates :review, presence: trueとし、入力がない場合にエラーを表示させるようにしています。 修正後のviewファイル こちらが完成形のコードになります。 ※スタイル適用時にレビュー星を枠で囲って表示するため、コードの記述順を変更しています。 app/views/travel_records/new.html.slim = simple_form_for @travel_record do |f| = render 'layouts/error_messages', model: f.object ・ ・ ・ = f.label :'オススメ度【必須】', required: false - is_error = f.object.errors[:review].present? #star class=(is_error ? 'form-control is-invalid' : 'form-control is-valid' if @travel_record.review? || is_error) .d-flex = f.hidden_field :review, id: :review_star = render 'shared/star', show_raty: 'new' div class=("invalid-feedback #{f.object.errors[:review].present? ? 'd-block' : 'd-none'}") | オススメ度を入力してください エラーメッセージのファイル app/views/layouts/_error_messages.html.slim - if model.errors.any? - model.errors.full_messages.each do | error_message | .alert.alert-danger.alert-dismissible.mb-2 role="alert" button type="button" class="close" data-dismiss="alert" span aria-hidden="true" &times; span.sr-only close = error_message それでは順を追って説明いたします。 赤枠の表示 まず初めに、エラー時に表示される赤枠の実装から行なっていきます。 app/views/travel_records/new.html.slim - is_error = f.object.errors[:review].present? # コードが重複しているため、変数に格納 #star class=(is_error ? 'form-control is-invalid' : 'form-control is-valid' if @travel_record.review? || is_error) 赤枠を表示させるにはbootstrapクラスのform-controlとis-invalidが必要になり、入力があった場合、緑枠を表示させるため、form-controlとis-validが必要になります。 また、入力の有無で表示を切り替えるため、三項演算子を使用して条件によって適切なクラスを付与するようにしています。 まず、三項演算子でクラスを付与する前にif @travel_record.review? || is_errorで条件分岐しています。 ※ この記述をしないと、未入力の場合でも緑枠が表示されてしまいます。 上記コードでは、f.object.errors[:review].present?でエラーの有無をチェックしています。エラーの場合はform-controlとis-invalidを付与して赤枠を表示させ、入力があった場合はform-controlとis-validを付与して緑枠を表示させています。 styleの修正 レビュー星を枠で囲って表示するため、styleの修正をしています。 app/assets/stylesheets/aplication.scss // エラーメッセージの設定 .form-control { height: auto; } form-controlのheightが悪さをしており、値をautoに変更した所、うまく表示することができました。 エラーメッセージの表示 次に、エラーメッセージ表示の実装を行なっていきます。 div class=("invalid-feedback #{is_error ? 'd-block' : 'd-none'}") | オススメ度を入力してください 赤文字のエラー文を表示するにはinvalid-feedbackクラスをもつ<div>タグが必要になります。 こちらも三項演算子を使用し、エラーの場合は、d-blockクラスを付与してエラーメッセージを表示させ、そうでない場合は、d-noneを付与して非表示にしています。 2つのクラスはどちらもbootstrapが用意しているクラスです。 d-block・・・display: block; d-none・・・display: none; 最後に 以上がBootstrap4 バリデーションエラーの表示方法でした! 思った以上に時間が掛かってしまったのですが、正常に動作した時の喜びは、その疲れを吹き飛ばしますね笑 これからも色んなことに挑戦し、学んだことを投稿していきたいと思います!! 間違っている箇所や分かりづらい箇所が多々あるかと思います。 その際は、気軽にコメントいただけれると幸いです。 最後までご覧いただき、ありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フォーム入力欄に最初から数字が入ってしまう現象をvalue: "" で対処した。

なぜかフォーム入力欄に最初から数字の 0 が入ってしまう現象が発生してしまった。 <div class="weight-bold-text"> 商品名 <span class="indispensable">必須</span> </div> <%= f.text_area :item_name, class:"items-text", id:"item-name", placeholder:"商品名(必須 40文字まで)", maxlength:"40" %> 原因はわかりませんが、ページを開くと入力欄に数字の0が既に入ってしまい対処に困りました。 <div class="weight-bold-text"> 商品名 <span class="indispensable">必須</span> </div> <%= f.text_area :item_name, class:"items-text", id:"item-name", placeholder:"商品名(必須 40文字まで)", maxlength:"40" , value: "" %> とりあえず value: "" を記述して入力欄を空にできましたが、何故このような現象が起きたのかは、未だに分かっていません…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsマンにとってPandasのDataFrame型がモヤモヤする理由

PandasのDataFrame型はモヤモヤする 当方、元々Rails歴3年で、最近Kaggleを始めた超初心者なのですが、Railsの経験が活かされる場面もあれば、逆にRailsの経験がバイアスになり混乱する場面もあります。入門してまず躓いたのは、PandasのDataFrame型です。特にdf['name']やdf.iloc[0]とやらで混乱してしまいました。 RailsとPandas テーブルデータの操作の違い 例えば、次のようなテーブルデータからオブジェクトを作成し、1行目・1列目を取り出す場合のコードの違いを比較します。 id name 1 田中太郎 2 佐藤花子 3 山田一郎 PandasのDataFrame型 data = { 'id': [1, 2, 3], 'name': ['田中太郎', '佐藤花子', '山田一郎'] } users = pd.DataFrame(data) # 1行目を取り出したいとき users.iloc[0] # 1列目を取り出したいとき users['id'] RailsのActive Record data = [ {id: 1, name: '田中太郎'}, {id: 2: name: '佐藤花子'}, {id: 3: name: '山田一郎'}, ] users = User.new(data) # 1行目を取り出したいとき users[0] # 1列目を取り出したいとき users.select('id') 何が違うのか? PandasもRailsも、テーブルのデータを操作するという点で共通ですが、決定的に違う点があります。それはズバリ、 Pandasは列でデータを区切るが、 Railsは行でデータを区切る という違いになります。 それぞれのdataの型を見比べればさらに明らかになります。 Pandasでは辞書型になっていますが、Railsでは配列型になっています。 実はPandasがusers['id']と書くのは、Pandasだから(あるいはPythonだから)ではなく、辞書型だから当然のことなのです。 なぜ違うのか?(私見) どちらもテーブルのデータを操作するという点で共通ですが、なぜPandasでは列でデータを区切り、Railsは行でデータを区切るのでしょうか? これは公式の見解ではなく、私見になります。 それは単純に、PandasとRailsで用途が違うから だと思います。 Pandasの用途はデータ分析なので、行よりも列を柔軟に扱いたい →データ分析では、列ごとに何かしらの処理をしたいことが多いです。例えばある列の平均値を算出したり、ある列の欠損値を埋めたりなど。逆に分析対象のデータの行数が増減したり、行ごとに抽出したりするシーンは比較的少ないのだと思います。なので列ごとにデータを区切ったほうが都合が良いです。 Railsの用途はWeb開発なので、列よりも行を柔軟に扱いたい →一方、Web開発では行ごとに何かしらの処理をしたいことが多いです。where文である条件に合致する行だけを抽出したり、行の新規追加、削除、更新など。逆にテーブルの列が増減したりは比較的少ないと思います。なので行ごとにデータを区切ったほうが都合が良いです。 PandasのDataFrameはスバラシイ 以上のように理解してから、PandasのDataFrame型と仲良くなれた気がします。公式の見解ではありませんが、少しでもPandas習得の助けになれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby on Rails】redcarpetを使ったMarkdown記法の拡張機能のまとめ

対象者 マークダウンを実装予定の方 gem redcarpetを使う予定の方 目的 redcarpetの拡張機能を一つひとつ理解しながら使用する 実際の手順と実例 1.gemの導入 Gemfile : gem redcarpet : bundle installを実行 2.拡張機能一覧 機能 説明 1 :no_intra_emphasis 単語の強調。**や--で囲う 2 :fenced_code_blocks フェンスで囲まれたコードブロックを解析します。3つ以上の~バックティックで区切られたブロックは、インデントする必要なしにコードと見なされます。オプションの言語名は、コードブロックの開始フェンスの最後に追加できます。 3 :autolink リンクを解析します。http、https、およびftpプロトコルの自動リンクは自動的に検出されます 4 :disable_indented_code_blocks 各行の前に4つのスペースがあるテキストをコードブロックに変換します。 5 :strikethrough 打ち消し線を使います。〜文字〜と入力すると打ち消しされます 6 :space_after_headers 見出しを作ります。#の数でh1〜h6まで分かれます。#の後に半角スペースが必要 ※随時更新 参照 red carpet 公式Github 投稿者コメント PFにマークダウンを実装したので、拡張機能をまとめました。関連記事として、マークダウン自体の実装方法も記事にする予定です。 My Profile プログラミング学習歴4ヶ月目のアカウントです! プログラミングスクールで学んだ内容や 自分が躓いた箇所等のアウトプットの為に発信しています。 もし、投稿した記事の中に誤り等ございましたら、 コメント欄でご教授いただけると幸いです。 
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】コントローラーからjavascriptへパラメータを渡す

はじめに ・本記事ではコントローラからjavascriptにパラメータを渡す方法を説明します。 controller→view→javascriptとviewを介してパラメーターを渡すことができます。 まず、コントローラからビューへは、インスタンス変数を使いパラメータを渡します。 /app/controller/books_controller.rb def index #パラメータを、インスタンス変数でビューに渡す @book = 'コントローラからjavascriptへパラメータを渡す方法' end view(ビュー)ではinputタグでtypeをhidden属性にし、valueとして受け取ります。 /app/views/books/index.html.erb <h1>indexページ</h1> <input type="hidden" id="book" value="<%= @book %>"> javascriptで、htmlの要素をdocument.getElementByIdで取得します。 /app/assets/javascripts/application.js window.onload = function () { const book = document.getElementById('book').value alert(book); } ブラウザで確認すると、コントローラから渡した@bookのパラメータが、javascriptのalertログで出力されていることが分かります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む