20210612のRubyに関する記事は18件です。

Railsをガイドに沿って基礎から学ぶ①

はじめに この記事はスキルアップを目的とした記録です。 前回に意味の分からないログイン画面を作成する投稿をしたところ、基礎知識が足りていないと感じたのでガイドに沿って1から勉強をしなおすことにしました。 現時点(2021/06/12)の物です。 わからない部分に関しては今後更新していきます。 1.教材 今回はRailsガイドを参考にしました。 今回はHello Railsを表示するまでの手順を記述し、ガイドを見て理解ができなかったところを深堀してお伝えしたいと思います。 2.Railsとは ①RailsとはRuby言語のフレームワーク ②Webアプリケーション簡単に設計出来るようになっている ③同一コードを繰り返さない事を推奨している ④設定よりも規約が優先される 3.新規プロジェクトの作成 3.1Railsのインストール 環境構築手順については以前投稿しているので割愛します。 3-2.新規アプリケーション作成 環境構築が終了したら新しいアプリケーションを生成します。 今回もCドライブ直下にアプリケーションを置きます。 $cd C:\ $rails new blog 生成が完了したらアプリケーションの中身を見ていきます。 上から初心者でも必要そうなものを紹介 ①app/ アプリケーションの構成に重要になるフォルダ。 MVCモデルに沿って作られている。 MVCモデルを知らない人は先にそちらを調べたほうが学習しやすいかもしれません。 ②config/ アプリケーションの設定ファイルが置いている。 使用頻度が高く重要。 気になる方はこちらのガイドから学ぶとよいと思います。 ③db/ データベーススキーマ、データベースマイグレーションファイルが置かれる場所。 appで記述しているModelと強いかかわりがあります ④public/ 外部からも接続できる範囲で、直接参照できるフォルダ。 Hello,Rails 4.1Webサーバーの起動 おさらい的な感じ サーバーを起動します。 $rails s 4.2画面にHelloを表示する Railsを画面上で表示するには、最低限ControllerとViewが必要。 更にルーティングの設定も必要になります。 まずはURLと画面を紐づけるためにルーティングを設定します。 ~/blog/config/routes.rb Rails.application.routes.draw do get "/articles" , to: "articles#index" end get "対象URL名" , to: "コントローラー名#アクション名"を追加しています。 getはHTTPメソッドを指定しています。 to:は"コントローラー名#アクション名"でコントローラーとビューの紐づけを行います。 るーていんぐの設定が完了したら次はコントローラーを生成します。 $rails generate controller Articles ※コントローラー名は原則複数形で定義します。今回はArticleの複数形Articlesです。2.Railsとはで紹介した規約の一部になります 生成が完了したら中身生成したコントローラーを確認して、アクションメソッド(index)を定義してあげましょう。 ※アクションメソッドとはルーティングにより指定されるときの名前です blog/app/controller/articles_controller.rb class ArticlesController < ApplicationController def index end end 次に画面表示のビューファイルを作って、中身を記述します。 ~blog\app\views\articles\index.html.erb <h1>Hello, Rails</h1> ControllerとViewを設定した時点で、routes.rbで定義した ~/blog/config/routes.rb get "/articles", to: "articles#index" でURLとコントローラーのアクション名とビューのファイルが紐づきます。 実際にアクセスすると下のようになります。 4.3アプリケーションのHomeを設定する http://localhost:3000 で開いてもArticlesに遷移させる方法があります。 config/routes.rbを開き、rootを追加します。 ~/blog/config/routes.rb get "/articles", to: "articles#index" 設定後に http://localhost:3000 を開くと、元々表示されていた画面がArticlesに変更されています。 さいごに 最後まで閲覧ありがとうございました。 記録として投稿しているため、間違っている部分や嘘をついている部分があるかもしれません。 もしお気づきの点がございましたらコメント等で教えてください。 今後もガイドに沿って理解を深めていこうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails APIモード + MYSQLをherokuにデプロイする流れ

RailsのAPIモードでデータベースをMySQLとして作ったアプリを初めてherokuにデプロイする過程でハマったところがあるので、結局何が正しかったのかを記録として書いておこうと思います。初心者なので至らぬ箇所もあるかとは思いますが悪しからず。 環境 ・Windows10 ・Ruby 2.6.6 ・Rails 6.1.3 ・MySQL2 0.5 ・heroku 前提 ・herokuアカウント登録済 ・heroku CLIインストール済(コマンドラインで$ heroku使うため  インストールはこちらからhttps://devcenter.heroku.com/ja/articles/heroku-cli) ・herokuクレジットカード登録済み(clearDB使うため。無料です) デプロイするソースをコミット #デプロイするアプリのディレクトリに移動し $ cd ~ #初期化 $ git init #ディレクトリ以下のファイルを選択し $ git add --all #コミットする $ git commit -m "first commit" herokuにログインし、新規app作成 下記コマンドでブラウザからログインします $ heroku login デプロイするアプリのディレクトリでapp作成します。 $ heroku app:create <appの名前> これによりアプリの公開URLがhttps://(appの名前).herokuapp.comとなります。 ちなみにアンダーバーが使えないようです。 リモートリポジトリの確認 $ git remote -v リモートリポジトリ heroku https://git.heroku.com/(appの名前).git が作成されていることを確認します。 先にgit initでローカルリポジトリを作成してからheroku createしたので、リモートリポジトリは自動で追加されるようです。 DBの設定 herokuのDBはデフォルトでPostgreSQLに設定されているようで、MySQLを使う場合手動で設定する必要があるようです。 下記コマンドで作成 $ heroku addons:create cleardb:ignite cleardb:igniteはignite(無料プラン)でherokuでMySQLが使えるcleardbを利用するという意味です。ただ、これを利用するためには無料ではあるけれど本人確認のためにクレジットカードをherokuに登録する必要があります。https://heroku.com/verifyから登録できます。英語で住所登録するのが慣れないため面倒でした。 ※このサービスが住所変換に便利でした。http://judress.tsukuenoue.com/ DBの環境設定 cleardbのURLを確認します。 $ heroku config 次のようなものが確認できます。 CLEARDB_DATABASE_URL: mysql://<ユーザー名>:<パスワード>@<ホスト名>/<データベース名>?reconnect=true このURLの情報を参考に各変数を設定します。 $ heroku config:add DB_NAME='<データベース名>' $ heroku config:add DB_USERNAME='<ユーザー名>' $ heroku config:add DB_PASSWORD='<パスワード>' $ heroku config:add DB_HOSTNAME='<ホスト名>' $ heroku config:add DB_PORT='3306' $ heroku config:add DATABASE_URL='mysql2://<ユーザー名>:<パスワード>@<ホスト名>/<データベース名>?reconnect=true' ここで、最後の行の部分でDATABASE_URL='mysql2://~'のようにmysql2となっていることに注意して下さい。MySQL2を使用しているのであれば2を入れるのを忘れずに。 次にapp/config/database.ymlを修正します。 database.yml production: <<: *default database: <データベース名> #変更 username: <ユーザー名> #変更 password: <%= ENV['APP_DATABASE_PASSWORD'] %> cleardbのURLで確認したやつですね。 変更をコミットしておきます。 $ git add -all $ git commit -m "update" herokuにデプロイ リポジトリをherokuにpushします。 $ git push heroku master マイグレーション $ heroku rake db:migrate 問題がなければ次のコマンドでhttps://(appの名前).herokuaopp.comにアクセスできます。 $ heroku open 補足 自分はDATABASE_URL=のところでmysql2ではなくmysqlになっていたので詰まってしまったのですが、デプロイできない原因を調べている中でapplication.rbやproduction.rbファイルでassets関連の修正を加えることで改善するという記事を多く見かけました。何も考えずにこの辺をいじってしまったことでさらにハマってしまうという結果となりました。 結果的には、RailsのAPIモードで作成したアプリであればassets周りは触らなくていいことが分かりました。データを返すAPIとしての機能だけならassetsは必要ないというのは納得できますね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ubuntu 20.04 LTSにtruffleruby 21.1.0をインストールする

毎度、ググっても出てこない小ネタを取り扱っております。 本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。 0. はじめに Ruby好きです。あまり得意ではないのですが、Ruby好きです。 しかし、ここ6年ほど触ってきませんでした。 特段、必要なかったというのもありますが、簡単なスクリプトを書くにはBashで十分だったのとディストリビューションに入っているRubyが古かったりして使いづらくなったり、スピード的に満足できなかったりして使わなくなっていました。一時期JRubyも使ってみようとしましたが、1回目の起動時間の重さに使わなくなっていました。 しかし、GraalVMで動くtrufflerubyというのがあると知りました。 パフォーマンスがよかったりするらしいので久しぶりに使ってみるかと思ったのが発端です。 Ruby https://www.graalvm.org/ruby/ 1. 環境とインストールするtrufflerubyのバージョン OS Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-74-generic x86_64) truffleruby 21.1.0 2. 必要なパッケージをインストール $ sudo apt update && sudo apt upgrade $ sudo apt install -y build-essential curl file git libssl-dev zlib1g-dev 3. brewをインストール $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)" $ test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv) $ test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv) $ echo "eval $($(brew --prefix)/bin/brew shellenv)" >>~/.profile 4. ruby-buildをインストール ruby-build は --HEADでインストールしないと途中でエラーが出ます。 $ brew install ruby-build --HEAD 5. rbenvをインストール 同時にruby-buildのpluginもいれておきます。 $ brew install rbenv $ mkdir -p "$(rbenv root)"/plugins $ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build 6. trufflerubyをインストール $ rbenv install --list | grep truffleruby $ rbenv install truffleruby-21.1.0 6-1. trufflerubyの動作確認 $ ls -la /home/ubuntu/.rbenv/versions/truffleruby-21.1.0/bin/ruby $ /home/ubuntu/.rbenv/versions/truffleruby-21.1.0/bin/ruby --version truffleruby 21.1.0, like ruby 2.7.2, GraalVM CE Native [x86_64-linux] $ /home/ubuntu/.rbenv/versions/truffleruby-21.1.0/bin/ruby -e 'print RbConfig::CONFIG["prefix"]' /home/ubuntu/.rbenv/versions/truffleruby-21.1.0 7. rbenvの設定 $ ruby_home=$(/home/ubuntu/.rbenv/versions/truffleruby-21.1.0/bin/ruby -e 'print RbConfig::CONFIG["prefix"]') $ echo $RBENV_ROOT $ rbenv root $ RBENV_ROOT=$(rbenv root) $ eval "$(rbenv init -)" $ rbenv init $ ln -s "$ruby_home" "$RBENV_ROOT/versions/truffleruby" $ echo "eval \"$(rbenv init -)\"" >> ~/.profile 7-1. 確認 $ rbenv shell truffleruby $ ruby --version truffleruby 21.1.0, like ruby 2.7.2, GraalVM CE Native [x86_64-linux] 8. trufflerubyをデフォルトのrubyに設定 $ rbenv local truffleruby 9. ベンチマークテスト こちらのベンチマークをやってみる TruffleRubyを動かしてみた - Qiita 以下のファイルを作成 hoge.rb #!/usr/bin/env ruby require 'benchmark/ips' def call i = 0 while i < 1000 i += 1 end end call; call; call; call; call # JITを効かせたいがために複数回呼び出す Benchmark.ips do |x| x.report('call') { call } x.compare! end gemでbenchmark-ipsをインストール $ gem install benchmark-ips 9-1. ベンチマーク結果 ubuntu@tuffleruby:~$ ruby ./hoge.rb Warming up --------------------------------------                 call   306.675k i/100ms Calculating -------------------------------------                 call      3.147M (±14.4%) i/s -     15.334M in   5.063475s ■ベンチマーク環境 CPU: model name: AMD Ryzen Embedded V1605B with Radeon Vega Gfx number: 4 CPU Memory Total: 4G 10. まとめ Rubyは生産性の高い言語だと思います。 死んだとかなんだか言われることもありますが、JavaもGraalVMで起動時間が短くなりシングルバイナリーで動くCloud Nativeな時代にフィットするものとして復活してきました。 Rubyもtrufflerubyにより起動時間が短くてシングルバイナリーで使いやすくなれば逆転のチャンスがあると思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】enumで対応ステータスを更新する

自作アプリを作成しているときに、管理者機能として、フォームからのお問い合わせの対応ステータスを更新する機能があったらいいなと思い、調べながら実装してみたので、メモしておきます! 実装画面はこんな感じです? 前提 構成(モデル等は生成済の前提で進めます) MODEL (FormInquiry) t.integer "user_id" t.text "content" t.integer "response_status", default: 0 t.datetime "created_at" t.datetime "updated_at" CONTROLLER (form_inquiries) 問い合わせ一覧(index action) 問い合わせ詳細(show action) 対応ステータス更新(update action) VIEWS 問い合わせ一覧(index.html) 問い合わせ詳細(show.html) ライブラリ - enum_help(enumをI18n化するgem) - devise(ユーザー/管理者認証) その他 - 会員(エンドユーザー)をUser、管理者をAdminとしてそれぞれテーブルを作成しています。 - 会員からフォームで問い合わせを受け付けると、管理者の問い合わせ一覧画面に表示されます。 - 管理者は問い合わせ詳細画面を開き、対応ステータス(未対応/対応中/対応済)の更新を行えます。更新すると、フラッシュメッセージが表示され、問い合わせ一覧のステータスも更新されます。 環境 ruby 2.6.3 rails 5.2.6 OS:Linux(CentOS) IDE:Cloud9 実装 enumとは? 「列挙型」という、整数が割り当てられた文字列を順に出力していく変数のことで、0を男性、1を女性のように、整数の値に何かしらの意味づけを行ってデータを管理することができます。「hashのkey部分の定数を保存すると、そのkeyに対応するvalueの整数が保存される仕組み」とのこと(【Rails】 enumチュートリアルより) 今回は、以下のような値で進めていくことにします。 { 0: outstanding(未対応), 1: in_progress(対応中), 2: closed(対応済)} STEP1. enumの定義 ? FormInquiryモデルのresponse_statusカラムに対して、enumを定義します app/models/form_inquiry.rb belongs_to :user enum response_status: { outstanding: 0, in_progress: 1, closed: 2 } 次に、enumを日本語化します。 ? Gemfileにenum_helpを追記して、保存したらbundle installします。 Gemfile gem 'enum_help' ? 英語名に対応する日本語の値を、ja.ymlに定義します。 config/locales/ja.yml ja: time: formats: default: "%Y/%m/%d %H:%M" enums: form_inquiry: response_status: outstanding: "未対応" in_progress: "対応中" closed: "対応済" ? もしアプリケーションのデフォルト言語が日本語になっていない場合は、設定しておきます config/application.rb module App class Application < Rails::Application # 略 config.i18n.default_locale = :ja end end STEP2. コントローラーに記述 対応ステータスの更新はupdateアクションで行います。 更新できたら、問い合わせ詳細画面にリダイレクトし、フラッシュメッセージを表示するようにしています。 app/controllers/form_inquiry_controller.rb class Admin::FormInquiriesController < ApplicationController before_action :authenticate_admin! before_action :set_form_inquiry, only: [:show, :update] def index @form_inquiries = FormInquiry.all.includes(:user).order(created_at: "DESC").page(params[:page]).per(10) end def show @user = User.find(@form_inquiry.user_id) end def update if @form_inquiry.update(form_inquiry_params) redirect_to admin_form_inquiry_path(@form_inquiry), notice: "対応ステータスを更新しました" else render :show, alert: "対応ステータスを更新できませんでした" end end private def form_inquiry_params params.require(:form_inquiry).permit(:response_status) end def set_form_inquiry @form_inquiry = FormInquiry.find(params[:id]) end end STEP3. ビューの記述 問い合わせ詳細(show) ? 対応ステータスの更新は、問い合わせ詳細画面で行うため、show.html.erbにセレクトボックスを実装します(※該当部分のみ抜粋しています) app/views/form_inquiries/show.html.erb <%= form_with model: [:admin, @form_inquiry], method: :patch, local: true do |f| %> <%= f.select :response_status, FormInquiry.response_statuses.keys.map {|k| [I18n.t("enums.form_inquiry.response_status.#{k}"), k]} %> <%= f.submit "変更" %> <% end %> ここでは、enumの値(未対応/対応中/対応済)のセレクトボックスを作成するため、mapメソッド(配列の要素の数だけブロック内で処理を繰り返して、新しい配列を返すメソッド)を使用します。 ここで何をしているか確認しておくと、 keysメソッドでハッシュオブジェクトからキーのみ配列の形で取り出している(outstanding/in_progress/closed) I18nのtranslateメソッド(I18n.t)でenumのキーの内容を翻訳している keysメソッドで取り出した値一つ一つに対しmapメソッドで処理し、二次元配列(配列の中に、配列が格納された形の配列のこと)を戻り値として返す 試しにrails cで返り値を見てみると、こうなっています? [3]はtranslateメソッドを使わなかった場合を一応出力してみた形です。 二次元配列の2つ目の要素(["対応中", "in_progress"])を選択して、検証ツールで見てみると、この二次元配列の1つ目の要素がoptionタグの表示部分に、2つ目の要素がvalueに入る仕組みであることがわかります。 これが他2つの二次元配列に対しても展開されて、セレクトボックスが生成されているようですね。 問い合わせ一覧(index) ? 7〜13行目で、一覧に表示する対応ステータスをif文を使って分岐させています。 日本語化した定数の値を表示したいので、カラム名の末尾に_i18nを追記します。 app/views/form_inquiries/index.html.erb <table> <% @form_inquiries.each do |form_inquiry| %> <tr> <td><%= l form_inquiry.created_at %></td> <td><%= link_to form_inquiry.user.name, admin_user_path(form_inquiry.user.id) %></td> <td> <% if form_inquiry.response_status == 'outstanding' %> <%= form_inquiry.response_status_i18n %> <% elsif form_inquiry.response_status == 'in_progress' %> <%= form_inquiry.response_status_i18n %> <% else %> <%= form_inquiry.response_status_i18n %> <% end %> </td> <td> <%= link_to "詳細", admin_form_inquiry_path(form_inquiry.id), class:'btn btn-sm py-0 btn-outline-secondary' %> </td> </tr> <% end %> </table> これで対応ステータスが更新できるようになりました! keysメソッドやmapメソッドの部分は、個人的にまだ理解が難しいのですが、言語化することで理解が少し深まったように思います。何かお気づきの点があれば、ぜひご教示ください。 参考資料 【Rails】enumをI18n対応させるenum_helpが便利すぎた 【Rails】 enumチュートリアル 【Ruby】 mapメソッドの基礎から応用をマスターして、効率的なコードを書けるようにしよう! Rubyでハッシュオブジェクトからキーや値を取り出す方法【初心者向け】 【初心者向け】i18nを利用して、enumのf.selectオプションを日本語化する[Rails]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】マージしていないにも関わらずdevelopのマイグレーションが更新された話

1.背景 現在、オンラインスクールにて共同開発に参加しており、タスクをGitHubのissueで管理しながら アプリを制作しています。 担当箇所の実装が終わると、マージする前にメンバー間のプルリクをローカルで確認してからメンターさんに確認して頂くようにしています。 ブランチ管理は以下のように行っており、featureブランチで作業→developブランチでマージという流れです。 ブランチ名 目的 備考 develop 開発用 機能実装用のブランチはここから切る feature/*** 機能実装用 派生元はdevelop 今回、マージしていない実装分の一部がdevelopブランチで更新されており、追加するかstash(回避)しないとブランチの切り替えができない状態でした。それを解消したのでまとめました。 2.環境 mac.os バージョン10.15.6 Ruby 2.7.2 Rails 6.1.3.1 psql (PostgreSQL) 12.6 3.今回起きていたこと ①origin/developとdevelopで差分が生じていた 状況を把握するために、origin/develop(リモートのdevelop)とdevelop(ローカルのdevelop)のコミットログを確認しました。 origin/developブランチのログ #origin/developブランチを確認 team_project % git fetch commit コミット番号 (HEAD -> origin/develop, origin/HEAD) Merge: マージしたコミット番号 Author: 人 <アドレス> Date: 日付 Merge pull request #41 from プロジェクト名/feature/*** Aを実装(プルリクのタイトル) ... ローカルのdevelopブランチのログ #developブランチで確認 team_project % git log commit コミット番号 (HEAD -> develop) Author: 人 <アドレス> Date: 日付 Bを実装 commit コミット番号 Merge: マージしたコミット番号 Author: 人 <アドレス> Date: 日付 Merge pull request #41 from プロジェクト名/feature/*** Aを実装(プルリクのタイトル) ... ローカルのdevelopブランチ上でBを実装というコミットをしており、ローカルのdevelopブランチが1つ進んでいる状態なので(本来は自分の作業ブランチでコミットが進んでいる以外はorigin/developとdevelopのコミットログは同じでないといけない)、origin/developブランチに戻す(同じ状態にする)コマンドを実行しました。 # developブランチ上で実行 team_project % git reset --hard origin/develop developブランチの差分がなくなり、再度rails db:migrateするとschemaが更新され、マージしていないモデルの実装が追加されました。原因はこれではありませんでした ②featureブランチでマイグレーションの更新をした後にリセットすることを忘れていた プルリクの確認を行うため、ローカルのdevelopブランチにプルリク分を取り込みます。 team_project % git switch develop # プルリク番号とブランチ名を確認 team_project % git fetch origin pull/プルリク番号/head:ブランチ名 team_project % git switch feature/*** # 今回はrails gでモデルとマイグレーションファイルを作成しているのでmigrateする team_project % rails db:migrate # feature/***ブランチで確認 team_project % rails db:migrate:status database: team_project_development Status Migration ID Migration Name -------------------------------------------------- up 年月日時      Create A up 年月日時 Create B up 年月日時 Devise create users up 年月日時 Devise create admin users up 年月日時 Create C  ★今回実装して増えた分 statusを確認すると、5つマイグレーションファイルが確認できます。 動作確認を行った後、そのままdevelopブランチに切り替えました。 # developブランチで確認 team_project % rails db:migrate:status database: team_project_development Status Migration ID Migration Name -------------------------------------------------- up 年月日時      Create A up 年月日時 Create B up 年月日時 Devise create users up 年月日時 Devise create admin users up 年月日時 ********** NO FILE ********** ★今回実装して増えた分 developブランチではマイグレーションファイルは存在しないのでNO FILEと表示されますが、statusは引き継がれます。その結果、developブランチでrails db:migrateをした際にdb/schema.rbにCモデルの内訳が更新されてしまった...ということでした。 4.マイグレーションを修正する対処法 パターン1:データベースを空にして再度入れ直す 今回の共同開発のデータはcsvデータを使用しており、またテストコードを手入力している訳ではないので データを空にする→再度入れ直すことで最新のdevelopブランチの状態にしました。 # developブランチで行う team_project % rails db:migrate:reset team_project % rails db:seed team_project % git status # 差分が出てこなくなった On branch develop Your branch is up to date with 'origin/develop'. nothing to commit, working tree clean パターン2:rollbackを使う featureブランチで行います。 developブランチ上で変更分を取り込むもしくはstash(回避)をしないとブランチの切り替えができないため、git checkout .コマンドで回避します。 team_project % git checkout feature/*** error: Your local changes to the following files would be overwritten by checkout: db/schema.rb Please commit your changes or stash them before you switch branches. # 変更を回避する team_project % git checkout . team_project % git checkout feature/*** # featureブランチで行う team_project % rails db:rollback team_project % rails db:migrate:status database: team_project_development Status Migration ID Migration Name -------------------------------------------------- up 年月日時      Create A up 年月日時 Create B up 年月日時 Devise create users up 年月日時 Devise create admin users # 今回実装して増えた分(Create C)が消える # developブランチに切り替えてmigrateを行う team_project % git checkout develop team_project % rails db:migrate こちらのrollbackはマイグレーションファイルが存在しない場合は実行ができないので、 今回のケース(↓)だとdevelopブランチではエラーとなります。(そのため、featureブランチでしかできませんでした。) # developブランチで確認 team_project % rails db:migrate:status database: team_project_development Status Migration ID Migration Name -------------------------------------------------- up 年月日時      Create A up 年月日時 Create B up 年月日時 Devise create users up 年月日時 Devise create admin users # rollbackしたくてもできない... up 年月日時 ********** NO FILE ********** 5.まとめ マージしていない場合でもマイグレーションファイルのstatusが引き継がれると知らなかったため、勉強になりました。 これからもエラーが出た際も一つ一つ検証し、解決したいと思います。 6.参考 1.リモートリポジトリfetch 2.gitでいろいろ取り消したい 7.最後に 記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。 読んでいただき、ありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Ruby on Rails] impressionistを導入して閲覧数をカウントする

上記のサイトを参考に実装しました。 気をつけなければいけないのは、RailsのverによってインストールするGemのverも変わるところです。 1.Gem //rails 6 gem 'impressionist' //rails 5 ~ gem 'impressionist', '~>1.6.1' $ bundle //インストール $ rails g impressionist $ rails db:migrate //テーブル作成 私はrails5.2なのですが、gem 'impressionist'で進めたため、エラーにハマりました。(ちゃんとREADMEは見ないといけませんね。) 2.Postテーブル作成 $ rails g model Post user_id:integer genre_id:integer post_image_id:string title:string content:text impressions_count:integer impressions_count:integerここがカウントを得るために必要なカラムになります。 dbファイルにて db class CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| t.integer :user_id t.integer :genre_id t.integer :impressions_count, default: 0 //0に設定する t.string :post_image_id t.string :title t.text :content t.timestamps end end end もう既にテーブルを作ってある方は追記しましょう。 3.Postテーブルの編集 app/models/post.rb class Post < ApplicationRecord is_impressionable counter_cashe: true //ここを追記 end counter_cache: trueとすることで、ページ表示の際にimpressions_countが+1されていきます。 4.controllerの編集 app/controllers/public/posts_controller.rb class Public::PostsController < ApplicationController impressionist :actions => [:show] //showで計測 def show @post = Post.find(params[:id]) impressionist(@post,nil,unique: [:session_hash.to_s]) //リロードして稼げないようにする。session_hashはstring型なので.to_sで変換 end end 5.viewに追記 app/views/posts/show.html.erb <%= @post.impressionist_count(:filter => :session_hash)%> //カウント数の記述を任意の場所に追記 controllerで指定したsession_hashでフィルターを掛ける。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RubyでRubyで配列を標準入力に使う方法

Rubyで配列を標準入力に使う方法です。 競技プログラムをされる方向けに説明いたします。 今回はpaiza様のRuby問題集を題材にしています。 ・文字列を文字列配列に標準入力して、数値に変換して、再度文字列で標準出力する場合 #文字列を入力してline配列に入れる line = gets.chomp.split(":") #line配列から要素を取り出して数値型に変換する。 hour = line[0].to_i minute = line[1].to_i #文字列型に変換して標準出力する。 puts hour.to_s puts minute.to_s ・mapを使う場合 #文字列を標準入力する line = gets #「:」で分けてmap関数を使ってhourとminute変数にそれぞれ数値に変換して代入する。 hour,minute = line.split(':').map(&:to_i) #標準出力する。 puts hour puts minute mapを使うほうが分かりやすいですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

productionモードでサーバー起動した際のエラー対処法

production.rbに以下の一文を加えます。 production.rb config.hosts << "localhost" そして再起動 $ bin/rails s -e production -b 0.0.0.0 解消しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails 6のbundle installが重すぎる

Ruby on Rails 6にしてから、bundle installにかなり時間がかかるようになってしまった。 Dockerを使って開発・デプロイをしているのだが、新規作成したばかりのプロジェクトでもCloud Build上でのビルドに10分以上かかってしまう状況だ。 原因: sasscのインストールが遅い 調べてみるとbundle installで発生する時間のうち、ほとんどの時間はsasscのインストールで発生している。同様の報告は多数上がっている。 sass/sassc-ruby - sassc is very slow to compile and install #189 Up to version 2.1.0, sassc shipped precompiled Linux binaries, but as of 2.2.0, the only precompiled versions are for mingw32. ... In the meantime, a workaround might be to pin sassc-ruby to version 2.1.0. Rails: Why is bundle install frozen up by sassc 2.4.0 Using an older version of sass solves the issue. I advise changing 6 to 5.1.0 in the Gemfile. This file will be located in your rails folder (the name you used when creating a new rails) sassc 2.2.0以降でmigw32用以外のコンパイル済みバイナリが含まれなくなり、linux系の環境ではbundle install時にネイティブビルドが発生することが直接的な原因のようだ。どうやら不具合ではなく、意図的にLinux系のコンパイル済みバイナリを含めるのをやめたようだ。 対策: 古いバージョンのsasscを指定するか、sass-railsのバージョンを下げる ワークアラウンドとして、sasscの2.1系を使うかsasscに依存しているsass-railsのバージョンを下げる方法が紹介されている。 基本的にはsasscのバージョンを下げる方が影響範囲が小さくて良さそうだ。 sass-rails(が参照しているsassc-rails)の最新版のdependencyをみると、必要なsasscのバージョンは「2.0以上」となっているので、2.1に下げることは可能だ。 # Use SCSS for stylesheets gem 'sassc', '2.1.0' gem 'sass-rails', '6' 結果: Cloud Buildでのビルド時間は10分から4分に短縮 sasscのバージョンを2.1に下げたことで、bundle installにかかる時間が大幅に短くなった。Cloud Buildでのビルドでも、10分かかっていたものが4分まで短縮され、大分開発・デプロイが快適になった。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails ログイン機能1 勉強用

deviseのインストール rails generate devise:install セットアップ 1. config/environments/development.rbファイルのendの前に記載 config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } 2.rootパスの設定 config/routes.rbファイルのendの前に記載 root to: "home#index" 3.flash messages(メッセージを表示する設定) app/views/layouts/application.html.erbフォルダのbodyに記載 <%# もしflash[:notice]があった場合表示させる %> <% if flash[:notice]%> <div class = "notification is-info"> <p class="notice"><%= notice %></p> </div> <% end %> <%#  エラーメッセージ %> <%#  もしflash[:alert]があった場合表示させる %> <% if flash[:alert]%> <div class = "notification is-danger"> <p class="alert"><%= alert %></p> </div> <% end %> 4.ターミナルで実行 実行するとviewsファイルにdeviseファイルが作られる ログイン画面 sessions/new.html.erb 新規登録画面 registrations/new.html.erb rails g devise:views
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails] 中間テーブルの特定のレコードを削除する

はじめに 私が作成中のオリジナルアプリで中間テーブルの特定の一つのレコードを削除したいときに、起こったエラーについて解説したいと思います。 各々の変数の名前の付け方が下手くそなのは目を瞑っていただけると幸いです。笑 簡単に、私の作成しているのはこのような中間テーブルです 一方的なフォロー機能のようなもので、studentがtextbookに対して「学習を始める」というボタンを押すと、students_textbookという中間テーブルにstudent_idとtextbook_idが一つのレコードに保存されるといった機能です。(イベントに参加するようなイメージの方がわかりやすいかも) そして、「学習をやめる」ボタンを押すと、その特定の中間テーブルのレコードが削除される仕組みです。 ここでエラーが起きました。 ArgumentError 発生 どうやら、destroyアクションの記述に問題があるようです。 現在のソースコード def destroy @found_recode = StudentsTextbook.where(student_id: current_student.id).where(textbook_id: @textbook.id) @found_recode.destroy redirect_to students_textbook_path(@textbook.id) end ちなみにbefore_actionで@textbookは下記のように定義されています。 現在のソースコード private def set_textbook @textbook = Textbook.find(params[:textbook_id]) end @found_recodeに代入した中身は、students_textbookテーブルの中の特定のレコードを消すために、whereメソッドで現在ログインしているstudent_idが含まれているレコードを全部取り出し、その中からさらに、whereメソッドで学習をやめるtextbookのidが含まれているレコードを取り出すと、特定の消したい一つのレコードが絞り出せると思ったのです。 結果的にこの考え方は間違っていなかったのですが、whereメソッドがどのような形で値を返していたかに問題がありました。あとdestroyの使い方です。 binding_pryで中身を確認 @found_recodeの中身をbinding.pryで調べてみます。 適当なtextbookに「学習をやめる」ボタンを押して@found_recodeを見ると [#<StudentsTextbook:0x00007fbb7f1d2e90 id: 29, student_id: 1, textbook_id: 16, created_at: Mon, 31 May 2021 17:46:02 JST +09:00, updated_at: Mon, 31 May 2021 17:46:02 JST +09:00>] このように表示されました。 たくさんあるレコードの中から特定の目的の一つのレコードが取り出せているかに見えます。しかし、これは配列で返ってきているのです。そして、その次の処理でdestroyメソッドを使用していますが、destroyメソッドは配列には使えないのです。これがエラーの原因でした。 そこでfind_byを使います。 find_byメソッドで解決する 先ほどのdestroyの記述の最後のwhereメソッドだけをfind_byメソッドに変更するだけで解決できました。 def destroy @found_recode = StudentsTextbook.where(student_id: current_student.id).find_by(textbook_id: @textbook.id) @found_recode.destroy redirect_to students_textbook_path(@textbook.id) end 最後に 今回学んだことはwhereメソッドは配列で値を返していたことと、destroyメソッドは配列には使えないってことですね。 後者は考えたら確かに、、、って感じですね。配列持ってこられても、どうやって削除するのかdestroyさんも困りますよね。すみません。 いつも思うんですが、エラーが発生して自分なりに答えを出して、それが解決につながったときの脳汁の分泌量は半端ないっすね。やめられないです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】 Decoratorパターンとは(コードは動けば良いわけではない)

1.はじめに 共同開発中にメンターさんから、「Decoratorについて調べてみて」とアドバイスを頂きました。 実装したい内容が実現できて安心してしまっていたので、「コードは動けば良いわけではないんだな...」と実感しました。 今回はDecoratorについて調べてみました。 2.環境 mac.os バージョン10.15.6 Ruby 2.7.2 Rails 6.1.3.1 psql (PostgreSQL) 12.6 3.MVCについて 冒頭でも少し触れましたが、メンターさんにDecoratorについてご紹介頂いたのは、「ビューのロジックに関することを、コントローラで定義してコードを書いていたから」だと思いました。 app/controllers/movies_controller.rb def index #動画の一覧を昇順(1,2,3...)にする @movies = Movie.order(created_at: :asc) #動画の番号を表示する(ために必要な変数を定義) ←ビューのロジックに関すること @base_number = ... end どこにコードを書くのか曖昧だと感じたので、まずMVCについて復習も兼ねて書いていきます。 3.1 モデル(M) データとデータに関わるビジネスロジック(アプリケーション特有の処理)をオブジェクトとして実装したもの。データベースの保存や読み込みを行う。 ※オブジェクト:関連する変数(値)とメソッド(動作)をまとめて、そのまとまりに名前を付けたもの。 3.2 ビュー(V) ブラウザに表示する画面、すなわちHTMLなどのHTTPレスポンスの中身を実際に組み立てる部分。必要に応じてコントローラからモデルなどのオブジェクトなどを受け取り、画面表示に利用する。 3.3 コントローラ(C) ユーザーが操作するブラウザなどのクライアントからの入力(リクエスト)を受け、適切な出力(レスポンス)を作成するための制御を行う。MとVのコントロールを行う。 4.Decoratorとは 原則として、モデルにはビジネスロジック、ビューではプレゼンテーション(見た目の)ロジックを記述するとした時に、「モデル固有のプレゼンテーションロジックはどこに書けばいいのか?」という問題が発生します。 ビューに書いた場合:モデル固有の処理なのに離れて分散してしまう。重複が発生しやすくなる。 モデルに書いた場合:コードの再利用性やメンテナンス性を損なう恐れがある。モデルが太る。 そこでDecoratorパターンを使うと、モデルごとや利用シーンごとにプレゼンテーションレイヤーの実装をまとめることができます。 アプローチの例 パターン1:モデルオブジェクトをインスタンス変数として保持し、ビュー用の処理を閉じ込めたクラスを作成して利用する 例:「アイスクリームのトッピングの処理のクラスを作り、トッピングクラスのインスタンス変数にアイスクリームのインスタンス変数を持たせる」ことでトッピングがのったアイスクリームを表現する。 パターン2:ビュー用の処理をモジュールとして定義し、ビューの文脈でモデルオブジェクトをextendして機能追加する モジュール:一連の振る舞いの設計図を一箇所にまとめたもの。 モジュールはオブジェクトを生成できず、includeメソッドを使ってクラスに取り込んで使用します。 includeはクラス(のインスタンス)に機能を追加しますが、extendはある特定のオブジェクトだけにモジュールの機能を追加したいときに使用します。 class VanillaIcecream # CashewNutsToppingIcecreamというモジュールを取り込みたい include CashewNutsToppingIcecream end パターン3:DraperやActiveDecoratorのgemを利用する gemを導入し、decoratorファイルに記述するという方法です。 # Gemfileに記述 gem 'draper' ①gemを導入し、bundle install(またはbundle)を実行します。 ②次に、 # generateはgでも可 # ターミナルで実行する rails generate draper:install rails generate decorator movie(モデル名) を順に実行します。 ③decorator.rbにコードを記入します。 movie(モデル名)_decorator.rb class movieDecorator < Draper::Decorator delegate_all # movie(モデル)のメソッドを全て呼び出せる def base_number(メソッド名) # モデルのメソッドを使用することもできる end end ④decoratorを用いたコードに書き換えます。 (1)コントローラ app/controllers/movies_controller.rb def index #動画の一覧を昇順(1,2,3...)にする @movies = Movie.order(created_at: :asc) #動画の番号を表示する(ために必要な変数を定義) ←ビューのロジックに関すること @base_number = ... end 書き換えた後(decoratorインスタンスを作成) app/controllers/movies_controller.rb def index # 複数のオブジェクトの場合はdecorate_collectionを使用する @movies = MovieDecorator.decorate_collection(Movie.order(created_at: :asc)) end (2)ビュー app/views/movies/index.html.erb <% @movies.each.with_index(1) do |movie, i| %> <p class="movie-title"> No.<%= @base_number + i %>:<%= movie.title %> </p> <% end %> 書き換えた後(decoratorメソッドを呼び出す) app/views/movies/index.html.erb <% @movies.each.with_index(1) do |movie, i| %> <p class="movie-title"> No.<%= movie.base_number + i %>:<%= movie.title %> </p> <% end %> おまけ draperやactive_decotratorを調べている際、「ヘルパーと何が違うのか?」混乱してきたので調べたところ、こちらに違いがありました。特定のモデルに関連しているビューの描写に関するものはdecoratorということですね。 5.まとめ 「モデル固有のプレゼンテーションロジックはどこに書けばいいのか?」という問題が発生した時に、「Decoratorパターンを使い、そこに記述しましょう」ということですね。 モデル→decorator→ ビュー とすることでモデルに関連したビューの表示をすることができました。 6.参考 1.大場寧子他, 現場で使えるRuby on Rails5速修実践ガイド, マイナビ出版, 2018. 2.Rubyのオブジェクトとは 3.draper 4.ActiveDecorator 5.decoratorを導入して、viewの記述をすっきりさせ、modelの肥大化を回避する【Day 3/30 2nd】 6.Rails Viewの表示のためにDecoratorを用意してHelperとModelを助ける 7.12. Decorator パターン 8.instance method Object#extend 9.Decoratorの役割とDraperについて 10.【入門】Draperを使ってみる 7.最後に 記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。 読んでいただき、ありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby on Rails プロジェクトを作成 勉強用

デスクトップにrubyディレクトリを作成 rubyディレクトリに移動 mkdir Desktop/ruby cd Desktop/ruby rubyのバージョンを2.6.3に指定 ※ディレクトリ内でバージョンを指定 ※バージョンが違うとエラーになる rbenv local 2.6.3 プロジェクトを作成 #rails new プロジェクト名 rails new project プロジェクト先に移動 #cd プロジェクト名 cd project railsのサーバーを立ち上げる rails s railsのサーバーを停止 Controlle + c プロジェクトURL http://localhost:3000/ vsCodeでプロジェクトを開く code . Gemfileのファイルにインストールするgemを記載して保存 #ログイン機能 gem 'devise' gem 'refile',require: 'refile/rails',github: 'manfe/refile' gem 'refile-mini_magick' #スタイル gem 'bulma-rails' Gemfileの変更を適用 bundle install
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rubyのsplat展開について

はじめに 『プロを目指す人のためのRuby入門』を読み進めていた時に気になった、splat展開についてまとめてみます。 Qiita初投稿ですので、どうかお手柔らかに。 そもそもsplat展開って何? Arrayオブジェクトにアスタリスクをつけることによって、配列が自動で展開される構文のことです。 文章で説明するよりも、実際に使い方を見せた方が分かりやすいと思います。 irb ary = [1, 2, 3] # splat展開を使わない [ary] #=> [[1, 2, 3]] # splat展開を使う [*ary] #=> [1, 2, 3] 上記を見ればわかる通り、配列を勝手に展開してくれます。 実用例 「別にいらない」と心の中で叫んだ方、いると思います。私もそうでした。 そんな方のために、今からsplit展開の実用例をお見せしますね。 例として、配列同士を連結させたい時は下記のような書き方になります。 irb ary = [1, 2, 3] [-1, 0] + a + [4, 5] #=> [-1, 0, 1, 2, 3, 4, 5] 長ったらしくて読みづらいですよね。こんな時にこそ、splat展開を使いましょう。 ary = [1, 2, 3] [-1, 0, *ary, 4, 5] #=> [-1, 0, 1, 2, 3, 4, 5] どうですか?読みやすくなりましたね。 最後に 最後に、この記事を書くにあたって参考にした『プロを目指す人のためのRuby入門』の著者の伊藤 淳一様、ありがとうございました。 実務ではRailsばかり触っているが、言語そのものの知見も同時に伸ばしたいという方にオススメの一冊です。 時間がある方はぜひ一度、じっくり読んでみましょう! プロを目指す人のためのRuby入門
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsの関連付けに関するエラーActiveRecord::HasManyThroughOrderErrorについて

1.エラー文 ActiveRecord::HasManyThroughOrderError at /posts Cannot have a has_many :through association 'Post#tags' which goes through 'Post#tag_relationships' before the through association is defined. .2やろうとしていること タグ機能をつけてpost投稿にタグを一緒に投稿できるようにしたい。 .3 原因 1.のエラー文を日本語訳してみたところ has_many :through association 'Post#tags'が、through associationが定義される前に、'Post#tag_relationships'を経由することはできません。 となっていたので post.rb has_many :tags, through: :tag_relationships has_many :tag_relationships, dependent: :destroy 中間テーブルと関連づけを定義するコードの順番が逆だということに気づきました。 4.解決 post.rb has_many :tag_relationships, dependent: :destroy has_many :tags, through: :tag_relationships とすることでこのエラーは解決しました! 最後までご覧いただき本当にありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【rails】複数カラムでの複数フリーワード検索を実装する

はじめに railsで複数カラムに対して、検索されたワードが部分一致したレコードのみを取得する検索機能を実装する。 また、複数ワードで検索された場合は、そのワードが全てどこかのカラムに入っているレコードのみを取得する。 構成 機能の構成としては、 複数ワードで検索する際はスペースでワードを区切ってフォームに入力してもらう。(疑似カラムsearch_wordを作る) スペースで検索ワードを分解して配列にいれる。 injectメソッドを使って繰り返しの処理をする。 (複数のワードがマッチしたレコードだけ取得する) 実装 実際には複数モデルでの検索も入れているので、form objectを使っております。 forms/search_bugs_form.html.erb class SearchBugsForm include ActiveModel::Model include ActiveModel::Attributes attr_accessor :search_word def search relation = Bug.distinct if search_word.present? search_words = search_word.split(/[[:blank:]]+/) search_words.inject(relation) do |result, word| relation = result.where('name LIKE ?', "%#{word}%").or(result.where('feature LIKE ?', "%#{word}%")).or(result.where('approach LIKE ?', "%#{word}%")).or(result.where('prevention LIKE ?', "%#{word}%")).or(result.where('harm LIKE ?', "%#{word}%")) end end end end 解説 まず、search_wordという擬似カラムを作ってそれをattri_accessorでアクセスできるようにします。 attr_accessor :search_word searchメソッドでは最初に、レコードの集合を取得してrelationに代入します。 relation = Bug.distinct 取得したsearch_wordをsplit(/[[:blank:]]+/)を使ってスペースで分解し、ワードを配列search_wordsに代入します。 search_words = search_word.split(/[[:blank:]]+/) /[[:blank:]]+/にすると、スペースが全角でも半角でも対応できるようになります。 続いて、injectメソッドを使います。 search_words.inject(relation) do |result, word| relation = result.where('name LIKE ?', "%#{word}%").or(result.where('feature LIKE ?', "%#{word}%")).or(result.where('approach LIKE ?', "%#{word}%")).or(result.where('prevention LIKE ?', "%#{word}%")).or(result.where('harm LIKE ?', "%#{word}%")) end 初期値をレコードの集合であるrelationに設定し、これがresultに代入されます。 wordには先程のsearch_wordsの検索ワードが順番に入ります。 検索ワードごとにor検索をして、最低1つのカラムの値に、その検索ワードが含まれているレコードをrelationに代入します。 そのrelationの結果がresultに代入され、次のワードがwordに代入されて、再びor検索が実行されます。 これを検索されたワードの数だけ繰り返します。 これで検索されたワードが2つ以上の場合は、その2つ以上のワードが全て、指定したカラムのどこかに入っているレコードのみを取得してきます。 参考 キーワードを全角込みの空白で区切る Ruby on Railsでinjectを使う方法を現役エンジニアが解説【初心者向け】 もっといい方法があればご教示ください?‍♂️
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pagyのページネーションの件数をページごとに設定する

はじめに RailsのページネーションのGem、pagy。 ページネーションだとkaminariが有名ですが、pagyはメモリの負担が少なくkaminariよりも高速で動きます。 ページネーションの表示件数を設定すると思うのですが、紹介している記事の多くはページごとにではなく、アプリケーション全体の設定として記述するやり方が多かったのでコントローラーのアクションごとに設定できる(つまり、ページごとに設定できる)やり方をご紹介します。 pagyの基本の設定方法 まずや基本的なPagyの設定方法。 config/initializers配下にpagy.rbを配置し、以下の記述を追加します。(追加したらサーバーの再起動必要) pagy.rb Pagy::VARS[:items] = 30 この場合は、30件ずつの表示になります。ちなみにpagyのデフォルトは20件ずつです。 pagyの設定をそれぞれにする ページネーションさせるのがひとつのページならいいのですが、ここは10件ずつでとやりたい場合ができず、 上記の例だと30件ずつになってしまいます。 なので、一覧ページは10件、管理画面はは30件ずつなどと細かく設定したい場合はcontroller.rbにアクションごとに記述します。 controller.rb def index @pagy, @users = pagy(User.all, items: 10) end def admin @pagy,@users = pagy(User.all, items: 30) end このようにitems :表示する数と記述すると、ページごとにページネーションさせる数を変えることができます。 ちなみにransackを使った時はこんな感じになるかと思います。 ransackの例 def index @q = User.ransack(params[:q]) @pagy,@users = pagy(@q.result, items: 30) end それでは〜。 参考サイト Qiita Rails 新興のgem pagyをつかってページネーション機能を実装する TechRacho Rails:「Pagy」gemでRailsアプリを高速ページネーション(翻訳)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ゼロ埋めの逆 Ruby

どのくらい経ったか定かではないけれども、一月くらいだろうか? Ruby であるプログラムを書き始めて。 Ruby は iRuby で書いていて、それ以前には全く興味がなかったので Ruby については知らない、ゼロ知識から一ヶ月くらいたったのではないだろうか、というところにいる。 自分でオブジェクトを開放できない以外は不安はない。させてほしい、自分で。 あるデータを読み出して、http 接続先の API にクエリに投げるというとこを書いていて、反応を見ている。 反応を見ていると、01という文字列よりも、1の方が、都合が良さそうである。つまり左側にゼロがない方がいい。 そこで、ゼロパッディング(ゼロ埋め)されたものから、ゼロを取りたい。如何に? まず、ゼロパッディング。 num = "%02d" % 1 1 は 01 となる。文字列。 これを戻そうとするわけで、 p num.to_i 01 から 1 になった。おしまい... と思っていたら、こんままでは書いていたプログラムの中では通らなかった。 書いていたのは、レギュラーエクスプレッションで取り出した数字列 01 だったのだ。 num = /\d+/.match('def01abc') puts num の01なので、このままではマッチしたオブジェクトということになる。そうなっているので、to_i ってメソッドなんて無いというエラーになる。 num.to_i 結果はエラー。 num = /\d+/.match('def01abc') num = num.to_s p num.to_i これでオッケー。 しかし、さらにこの書いていたプログラムでは、さらにその01を文字として他の変数に付け足したいところだったので、こうなる。 num = /\d+/.match('def01abc') text = 'book_title' text += ' ' + num.to_s.to_i.to_s p text "book_title 1" こういうのでやってみてね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む