- 投稿日:2020-10-28T23:08:28+09:00
Rails+herokuでLINEbotを作ってみた
作ったもの
毎朝ゴミ出しの通知をしてくれるBOTがあったら便利だなーと思い、
勉強がてら作ってみました。使用言語
Ruby
Ruby On Rails6
Heroku
LINE Messager APISTEP 1 メッセージをオウム返しするLINEBOTの作成
こちらについては他の方が詳しく投稿されているので割愛します。
参考記事
https://qiita.com/y428_b/items/d2b1a376f5900aea30dc
https://qiita.com/natsukingdom-yamaguchi/items/e84dffdd90d7f5ef8224
STEP 2 PUSHメッセージ
タスクを追加し、決まった時間になったらメッセージを送信します。
タスクの作成
$rails g task reminder_task
次にコントローラーを生成
$rails g controller webhook trash
descriptionとtaskを記述
lib/tasks/reminder_task.rakenamespace :reminder_task do desc "ここにタスクのお題" task :trash => :environment do webhook = WebhookController.new puts webhook.trash end end次にWebhookcontrollerのアクションを定義
app/controllers/webhook_controller.rbdef trash puts "メッセージ" endここでrakeタスクに追加されているか確認
$ rake -T rake reminder_task:trash タスクのお題
追加されているか確認が出来たら
$ rake reminder_task:trash
【メッセージ】が送信されたらOK
環境変数の設定
PUSHメッセージを利用する場合は環境変数を設定しなければなりません。
環境変数については以下を参照しました。
https://qiita.com/yuichir43705457/items/7cfcae6546876086b849
https://qiita.com/noraworld/items/bfa80811c9e30b4474af設定方法
dotenvをgemに追加します
gem 'dotenv-rails'.envファイルをアプリケーションディレクトリのルートディレクトリに作成
(appやgemfileがある場所に作成)LINEチャネルの諸々を設定
/.envLINE_CHANNEL_SECRET='xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' LINE_CHANNEL_TOKEN='yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy' LINE_USER_ID='zzzzzzzzzzzzzzzzzzzzzz'Webhookcontrollerのtrashアクションを書き換える
app/controller/webhook_controller.rbclass WebhookController < ApplicationController require 'line/bot' def trash message = { "type": "text", "text": WebhookController.contents } client = Line::Bot::Client.new { |config| config.channel_secret = ENV["LINE_CHANNEL_SECRET"] config.channel_token = ENV["LINE_CHANNEL_TOKEN"] } response = client.push_message(ENV["LINE_USER_ID"], message) end def self.contents date = Date.today case date.strftime('%a') when "Mon" "今日は月曜日、燃えるゴミの日!" when "Tue" "無し!" when "Wed" "今日は水曜日、燃えないゴミ・段ボールの日" when "Thu" "今日は木曜日、普通ゴミの日だわ!" when "Fri" "今日は金曜日、缶・瓶・ペットボトルの日!" when "Sat" "一週間お疲れ!今日は無し!" else "" end end endHerokuにPushしスケジューラーを設定すれば、メッセージが届くはずです。
最後に
rubyを勉強して初めて作ったサービス?になりますので、間違ってる点などが多々あるかと思われます。
その際は、ご指摘いただけると嬉しいです!(参考記事の方々、ありがとうございました。)
- 投稿日:2020-10-28T22:48:37+09:00
【Ruby On Rails】FactoryBotを用いてRSpecでモデル単体テストを行うと外部キーが入力されていないことでエラーになる
初投稿
備忘録です。エラー背景
RSpecでテストを実行する際に、FactoryBot内に記述すべき外部キーについて未入力であった。
FactoryBot.define do factory :order_form do zipcode {'123-4567'} prefecture_id {1} city {'亜嗚呼市あああ区'} address {'亜嗚呼1-1-1'} phone_number {'09012345678'} end endエラー内容
OrderForm 商品購入 商品購入がうまくいく時 全項目が存在すれば購入できる (FAILED - 1) Failures: 1) OrderForm 商品購入 商品購入がうまくいく時 全項目が存在すれば購入できる Failure/Error: expect(@order_form).to be_valid expected #<OrderForm:0x00007fe44961c1e8 @zipcode="123-4567", @prefecture_id=1, @city="亜嗚呼市あああ区", @address="亜嗚呼1-1-1", @phone_number="09012345678", @validation_context=nil, @errors=#<ActiveModel::Errors:0x00007fe448aeeaa0 @base=#<OrderForm:0x00007fe44961c1e8 ...>, @messages={:user_id=>["can't be blank"], :item_id=>["can't be blank"]}, @details={:user_id=>[{:error=>:blank}], :item_id=>[{:error=>:blank}]}>> to be valid, but got errors: User can't be blank, Item can't be blank # ./spec/models/order_form_spec.rb:10:in `block (4 levels) in <top (required)>' Finished in 0.17606 seconds (files took 1.9 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/models/order_form_spec.rb:9 # OrderForm 商品購入 商品購入がうまくいく時 全項目が存在すれば購入できる注目すべき点はこちらです。
@errors=#<ActiveModel::Errors:0x00007fe448aeeaa0 @base=#<OrderForm:0x00007fe44961c1e8 ...>, @messages={:user_id=>["can't be blank"], :item_id=>["can't be blank"]}, @details={:user_id=>[{:error=>:blank}], :item_id=>[{:error=>:blank}]}>> to be valid, but got errors: User can't be blank, Item can't be blank外部キーとしていたuser_id、item_idが空欄になっているということを教えてくれました。
エラー修正
エラー内容より、FactoryBot内の記述を修正すれば良いことがわかりました。
あとは指示された通りuser_idとitem_idをFactoryBotに追加してあげれば大丈夫です。user_id { FactoryBot.create(:user).id } item_id { FactoryBot.create(:item).id }修正後のターミナル
OrderForm 商品購入 商品購入がうまくいく時 全項目が存在すれば購入できる Finished in 0.3807 seconds (files took 3.22 seconds to load) 1 example, 0 failures
成功です。
- 投稿日:2020-10-28T22:35:01+09:00
rails + postgres sqlでポートフォリオ作成
記事の概要
私が作成したポートフォリオの解説です。
作った背景、機能、苦労した点、工夫したところ、今後の課題をまとめました。実際に作成したサイトやソースコードは下記のリンクからご覧いただけます。
https://github.com/rotosiri-zu/pcparts
https://pcparts-staging.herokuapp.com/作った背景
趣味で自作PCを作成したりしているのですが自分が知らないPCパーツのスペックをしりたい他のユーザーはどんなPCパーツを使っているのか気になり、自作PCを作成している他のユーザーからの紹介で使用しているPCパーツや購入したもので作成するときのパーツ選びに参考になればと思いWebアプリを作りました。
また、現職を退職し、Web系開発企業のバックエンドエンジニアになろうと考えていたので、
このアプリを転職活動のポートフォリオとすることに決めました。スペック
言語
Ruby 2.6.6
フレームワーク
ruby on rails 5.2.4.3
cssフレームワーク
bootstrap4
データベース
postgres sql
バージョン管理
github
本番環境
heroku + Amazon S3
主な機能
ログイン・ログアウト機能
登録したユーザーやゲストログインでログインできます。ホーム画面からもゲストログインでログインすることができます。
投稿機能
会員登録することで自由に投稿することができます。
入力に誤りがあれば、投稿はされずエラ-メッセージが表示されます。マイページ機能
ユーザーが投稿したアイテム一覧を確認することができます。
商品名検索機能
投稿時に記入したタイトル名で検索できます。
カテゴリー検索機能
投稿時に選択肢したカテゴリーで検索できます。
口コミ投稿機能
PCパーツの感想を投稿できます。
入力に誤りがあれば、投稿はされずエラ-メッセージが表示されます。アイテム更新・削除機能
投稿したアイテムを更新・削除ができます。
口コミ更新・削除機能
投稿した口コミを更新・削除ができます。
苦労した点
カテゴリー機能の機能追加でIDエラーの解決に時間がかかったところです。
解決した方法は検証と仮説を立てその後に検索して調べ見つけた記事の通りやってみたところ解決しました。工夫した点
ホーム画面からゲストログインできるようにしホーム画面に機能の説明を記載したり説明とアイテム投稿一覧の境目に黒線を追加、詳細画面の口コミ投稿のフォームに黒線を追加してわかりやすくしました。
なぜruby on railsの言語を選んだのか
ruby on railsを選んだ理由は初心者が入りやすく参考にする記事やコミニティが多いからruby on railsを選択しました。
今後の課題
今後の課題はテストコードがかけていないのでテストの実装やパンくずリストの実装を追加しようと考えております。
参考文献
- 投稿日:2020-10-28T22:13:42+09:00
railsでapp名を変更する方法
環境
Rails 6.0.3.4
流れ
1.gemを入れる
2.dbを削除(不要なら)
3.app名を変更
4.db作成手順
1.gemを入れる
Gemfileに以下を追記
gem 'rename'bundleする
$ bundle2.dbを削除(不要なら)
特になければdbを削除
$ rake db:drop3.app名を変更
$ rails g rename:into {{新しいapp名}}作成したapp名のフォルダへ移動
$ cd ../{{新しいapp名}}4.db作成
dbを作成して
$ rake db:createマイグレーションする
$ rake db:migrate
- 投稿日:2020-10-28T22:00:54+09:00
東西南北の緯度経度から任意の数に分割する
# 縦横何分割するか DEVIDE_COUNT = 7 # 配列の中央値 cneter_index = (DEVIDE_COUNT / 2) + (DEVIDE_COUNT % 2) # 東西南北 origin_n = 0 origin_s = 50 origin_w = 100 origin_e = 200 north_south_unit = (origin_s - origin_n).fdiv(DEVIDE_COUNT) west_east_unit = (origin_e - origin_w).fdiv(DEVIDE_COUNT) # 北から南、西から東へ分割していく distance_rankは中心から遠いほど大きくなる Mesh = Struct.new(:nl, :sl, :el, :wl, :distance_rank) results = [] (1..DEVIDE_COUNT).each do |ns_count| (1..DEVIDE_COUNT).each do |ew_count| results << Mesh.new( origin_n + (north_south_unit * (ns_count -1)), origin_n + (north_south_unit * ns_count), origin_w + (west_east_unit * (ew_count -1)), origin_w + (west_east_unit * ew_count), (cneter_index - ns_count).abs + (cneter_index - ew_count).abs ) end end pp results.sort_by(&:distance_rank)
- 投稿日:2020-10-28T21:44:36+09:00
【忘備録】Rubyをやってみて何度も調べたコマンド一覧
はじめに
Rubyを半年程さわってみてなんとなく調べる頻度が多かったコマンドをここでまとめてます。初学者兼初投稿なのでコメントやLGTMなどでフィードバック頂けると励みになります。よろしくお願いします。
Capistrano関連
デプロイ実行 $ bundle exec cap production deploy 1つ前の状態にロールバック $ bundle exec cap production deploy:rollbackunicorn関連
起動状態を確認する $ ps auxwww | grep unicorn プロセスを終了する $ kill -9 ○○○○○○ すべてのログを確認する ($ cd /var/www/app/log にて) $ less unicorn.staderr.log 直近10件のログを確認する ($ cd /var/www/app/log にて) $ tail unicorn.staderr.lognginx関連
再起動する $ sudo service nginx restart すべてのログを確認する (本番環境のホームディレクトリにて) $ sudo less /var/log/nginx/error.logMySQL関連
起動状況を確認する $ sudo service mysqld status 起動する $ sudo service mysqld start本番環境まわりのコマンドばかりになってしまいましたが、過不足があれば随時更新していきます。
- 投稿日:2020-10-28T19:28:52+09:00
【Ruby on Rails】try(:[ ], :key)を読み解く
はじめに
user.try(:[],:name)初めてこのコードを見た時、
「なんで空の配列をメソッドの部分に入れているんだ、、、?」
と思いました。
Ruby(Rails)の文法をすっ飛ばしてきた弊害ですね、、、そもそもRailsのtryとは?
Active Supportに搭載されているメソッド (Rubyだけでは使えない)
対象のオブジェクトがnilでない時のみ、指定したメソッドを使う
第一引数に使いたいメソッド、第二引数にその引数(必要であれば)を与えますuser = {name: "test"} # user[:group]がnilであるため、メソッドエラーが起きる user[:group].replace("A") # => NoMethodError: undefined method 'replace' for nil:NilClass # nilな対象に対してtryを使うとエラーは起きず、nilが帰ってくるだけ user[:group].try(:replace,"A") => nil空の配列がメソッドに?
それでは本題ですが、rubyのHashには[]のメソッドがあります。
引数にkey名を取ってそのvalueを返します。user.[] :name => "test" # これはuser[:name]と同じちなみに、「+」などもメソッドとして使えます。
user[:name].+ 2 => "test2"
今回の場合はtryとこのメソッドの組み合わせなので
user.try(:[],:name) => "test"という結果が返ってきます。
まとめ
[]についてなかなかヒットしなかったので少し理解に苦しみました。
ruby/railsの文法を勉強し直します、、、
- 投稿日:2020-10-28T19:16:43+09:00
【Rails】星★の評価を実装する(入力、保存、表示)
はじめに
開発しているメモアプリにランク付けをしていきたいと思います。
今回は三段階で評価していこうと思います。
それに伴い、星★による評価の入力・保存・表示について学習していきます。参考
マイグレーションファイルにカラムを追加
notesテーブル(メモテーブル)のrateカラム(型:float)に評価値を保存する
すでに、テーブルとカラムは作成されていることを前提に進めます。カラムは、半分の星による評価を行う場合、「0.5」や「1.5」という値を保存することになるため、float型にしておく必要があります。
もし、integerやstringの型として作成してしまっていた場合は、データベースによって変更方法は異なりますが、型の変更が必要になります。下記の記事でこの型の変更の沼にハマってしまった時の解決策を書いています。
class CreateNotes < ActiveRecord::Migration[5.2] def change create_table :notes do |t| t.text :title t.integer :user_id t.integer :category_id t.text :explanation t.float :rate t.timestamps end end endrails db:migrate:resetjavascriptの読み込み、★画像の読み込み
上記参考リンクを確認しながら、javascriptの読み込みと星の画像の読み込みを行います。
やり方(2種類)
①jQuery Ratyを使用するには、https://github.com/wbotelhos/raty からjquery.raty.jsをダウンロードする。
ダウンロードしたスクリプトをウェブサイトの任意の場所に配置する。
app/javascriptsのフォルダの中にダウンロードしたjquery.raty.jsファイルを配置する
②jQuery Ratyを使用するHTMLの中でJavaScriptを読み込む。RatyはjQueryのプラグインなので、jQueryのスクリプトも必要である。
<script src="/js/jquery.min.js"></script> <script src="/js/jquery.raty.js"></script>今回は①のやり方で実装していきます。
*ここでJavaScriptも定義していきます。
javascripts/application.js
ファイルに追加する//= require rails-ujs //= require activestorage //= require turbolinks //= require jquery #追加 //= require jquery_ujs #追加 //= require_tree .Gemファイル追加
gem 'jquery-rails'budle installモデルの記述(紐付け)
note.rbclass Note < ApplicationRecord # ユーザーとの紐付け belongs_to :user,optional: true # バリデーション validates :title, presence: true validates :explanation, presence: true # カテゴリーと紐付け belongs_to :category validates :rate, presence: true validates :rate, numericality: { # only_integer: true, less_than_or_equal_to: 3, greater_than_or_equal_to: 1, } # numericality=空を許可する numericalityは、デフォルトでは小数も許容してしまいます。rateカラムでは整数のみ許可したいので、 only_integerを。 例 validates :param3, :numericality => { :less_than_or_equal_to => 3} # 数字が3以下であるか validates :param3, :numericality => { :greater_than_or_equal_to => 1 } # 数字が1以上であるか endコントローラーの記述
notes_controller.rbclass NotesController < ApplicationController before_action :authenticate_user! def new @note = Note.new end def create # @note = Note.new(note_params) @note = current_user.notes.build(note_params) @note.save redirect_to notes_path end def index # is_validがマッチするレコードを全て取得 @categorys = Category.where(is_valid: true) @q = Note.all.ransack(params[:q]) @notes = @q.result(distinct: true) end def show @note = Note.find(params[:id]) end def edit @note = Note.find(params[:id]) end def update @note = Note.find(params[:id]) @note.update(note_params) redirect_to note_path end def destroy @note = Note.find(params[:id]) @note.destroy redirect_to notes_path end def search @categorys = Category.where(is_valid: true) @category = Category.find(params[:id]) @q = @category.notes.all.ransack(params[:q]) @notes = @q.result(distinct: true).page(params[:page]) @title = @category.name render 'notes/index' end private def note_params params.require(:note).permit(:title, :category_id, :explanation,:user_id,:rate) end endここでは
note_params
メソッドにrate
カラムを追加します。メモ登録フォームを作る
_form.html.erb<%= form_with model:note, local: true do |f| %> <div class='form-group'> <%= f.label :タイトル %> <%= f.text_field :title, class: 'form-control', id: 'note_title' %> </div> <div class='form-group'> <%= f.label :カテゴリー %> <%= f.collection_select :category_id, Category.all, :id, :name %> </div> <!-- 評価 --> <div class="form-group row" id="star"> <%= f.label :rate,'重要度 ', class:'col-md-1 col-form-label' %> <%= f.hidden_field :rate, id: :review_star %> </div> <div class='form-group'> <div id='editor'> <%= f.label :内容 %> <%= f.text_area :explanation, rows: 10, class: 'form-control', id: 'note_explanation', "v-model" => "input", name: "note[explanation]" %> <h2><i class="fas fa-eye"></i> Preview</h2> <div id="preview-field" v-html='input | marked'> </div> <div ></div> </div> <%= f.submit '登録', class: 'btn btn-success' %> </div> <% end %> <!-- リアルタイムプレビュー --> <script type="text/javascript"> window.onload = function() { new Vue({ el: '#editor', data: { input: '<%== j @note.explanation %>', }, filters: { marked: marked, }, }); }; <!-- 評価 --> $('#star').raty({ size : 36, starOff: '<%= asset_path('star-off.png') %>', starOn : '<%= asset_path('star-on.png') %>', starHalf: '<%= asset_path('star-half.png') %>', scoreName: 'note[rate]', half: true, }); </script>ポイントは下記
# ★の半分の入力ができるようにするため half: true,星による評価の表示
メモ一覧にて、★を表示したい。
上記の「★の入力、保存」と異なる点は、1.入力はせず表示する 、 2.繰り返し処理をするということになります_notes_index.html.erb<div class='row'> <table class='table'> <thead> <tr> <th>タイトル</th> <th>カテゴリー</th> <th>重要度</th> </tr> </thead> <tbody> <% @notes.each do |note| %> <% if user_signed_in? && current_user.id == note.user_id %> <tr> <td> <%= link_to note_path(note) do %> <%= note.title %> <% end %> </td> <td><%= note.category.name %></td> <!-- 評価 --> <td> <div id="star-rate-<%= note.id %>"></div> <script> // 繰り返し処理でもidをidを一意にできるようにnote_idを入れる $('#star-rate-<%= note.id %>').raty({ size: 36, starOff: '<%= asset_path('star-off.png') %>', starOn : '<%= asset_path('star-on.png') %>', starHalf: '<%= asset_path('star-half.png') %>', half: true, // 読み込みだけで入力できない readOnly: true, score: <%= note.rate %>, }); </script> </td> </tr> <% end %> <% end %> </tbody> </table> </div>ポイントは下記
# 繰り返し処理を実行してもidを一意に保てるようにreview.idを埋め込む <div id="note-rate-<%= note.id %>"></div> # 読み取り専用(入力できない) readOnly: true, # 星の入力値を読み込む score: <%= note.rate %>,これで完成!
最後に
説明が分かりづらかったりすると思いますがご了承ください。
また、間違っているところがあればご教授いただけると幸いです。
- 投稿日:2020-10-28T18:55:08+09:00
Railsで多言語化対応する!
今自分が開発しているwebアプリを英語に対応しようとしたときにやったことを書いていきます。
インストール
Gemfilegem 'rails-i18n'インストール
bundleconfig/application.rbに設定
config/application.rbconfig.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] # 対応する言語。今回は日本語(ja)と英語(en)だけ config.i18n.available_locales = %i(ja en) # 上記の対応言語以外の言語が指定された場合、エラーとするかの設定 config.i18n.enforce_available_locales = true # デフォルトの言語 config.i18n.default_locale = :jacontroller
controller/application_controller.rbbefore_action :set_locale def set_locale I18n.locale = locale end def locale @locale ||= params[:locale] ||= I18n.default_locale end def default_url_options(options={}) options.merge(locale: locale) endroutes.rb
routes.rbscope '(:locale)', locale: /#{I18n.available_locales.map(&:to_s).join('|')}/ do root "posts#index" resources :posts endscopeで囲んだ部分が多言語対応するページです。
多言語化
en.ymlとja.ymlを作ります。
多言語化したい文にviews<%= t(:hello) %>と書きます。helloのところは自由に変えてください
ja.ymlja: hello: こんにちは # モデルは全て activerecord を起点にする。 # これにより、User.model_name.human / User.human_attribute_name({attr_name})でアクセス可能。 activerecord: models: user: 'ユーザー情報' attributes: user: name: '名前' mail: 'メールアドレス' url: 'ウェブページ'en.ymlen: hello: "hello" # モデルは全て activerecord を起点にする。 # これにより、User.model_name.human / User.human_attribute_name({attr_name})でアクセス可能。 activerecord: models: user: 'User' attributes: user: name: 'Name' mail: 'Email' url: 'URL'こんな感じでやっていきます。
- 投稿日:2020-10-28T17:51:33+09:00
bundler
動作のメモ
動くようになったら使えるようにしましょう.shebangというのを設定して,さらにexecutableに直します.
- mv hello.rb hello
- #!/usr/bin/env ruby
- chmod a+x hello
置き場所を工夫すれば,とても便利です.
. # very local
- ./bin # project
- ~/bin # user
- gem # all users
tight bindingという考え方があります.これは,必要なファイルを出来るだけ必要な場所に近いところに置いておくことを意図しています.そうすると可搬性が増すから.
execなどの種類で整理したり,~/binなどに置いておくとそのうち爆発します.localはlocalに必要なprojectで実行できるように.さらに,チョコチョコ直すのも気兼ねなくできるようになります.ここでしか使わないから.
でも,便利なものや,いろいろな場面で使う共通のアプリはいろいろなところから使えると便利ですよねそういう時にはgemにしちまいましょう.
bundler
- gem install bundler
- bundle gem hogehoge -b
です.これでOKです.あとは,少し修正です.
rm -rf hogehoge/.git
bundleはdefaultでgitでのbackup管理をします.なので,その設定をする必要がありますが,今は,それを外します.
- source ~/git_hub/ruby_docs/chart_style_ruby/./c0_bundler.org
- 投稿日:2020-10-28T17:17:56+09:00
【Rails】遷移前のURLのパス名を取得してリンク先を変更する
環境
rails 6.0.3
説明
遷移前のページの
URL
内のパス名によって、ページに表示するリンク先を分岐させる方法。補足
パス名とは?
https:///www.example.com/user
だった場合は、パス名は/user
該当のviewファイル<% if URI(request.referer).path == 'パス名' %> #前のページが指定したパスだった場合のリンク先 <% else %> #その他のリンク先 <% end %>
request.referer
は文字列を返す。Ruby
のURIモジュール
を使用して、request.referer
をラップすると、パスだけを要求することができる。参考記事
URLすべてを取得して、ページに表示するリンク先を分岐させる方法
https://qiita.com/taka_571/items/9b1c82d8fcc602df8a1a
- 投稿日:2020-10-28T17:17:56+09:00
Railsで遷移前のURLのパス名を取得してリンク先を変更する
- 投稿日:2020-10-28T16:28:31+09:00
Expected exactly 2 elements matching "a[href="/"]", found 0.. のエラーメッセージ
Expected exactly 2 elements matching "a[href="/"]", found 0..のエラーメッセージ
Railsチュートリアルをやっている時にエラーが起きたので、解決した方法を書きます。やっていたのは5章の「5.3.4 リンクのテスト」の所です。
エラーメッセージはFAIL["test_layout_links", SiteLayoutTest, 2.2938910419998138] test_layout_links#SiteLayoutTest (2.29s) Expected exactly 2 elements matching "a[href="/"]", found 1.. Expected: 2 Actual: 1 test/integration/site_layout_test.rb:10:in `block in <class:SiteLayoutTest>' 1/1: [===================================] 100% Time: 00:00:02, Time: 00:00:02 Finished in 2.29667s 1 tests, 2 assertions, 1 failures, 0 errors, 0 skips }
私の場合はこのファイルに異常がありました。
app/views/layouts/_header.html.erb<header class="navbar navbar-fixed-top navbar-inverse"> <div class="container"> <%= link_to "sample app", root_path, id: "logo" %> <nav> <ul class="nav navbar-nav navbar-right"> <li><%= link_to "Home", 'root_path' %></li> <li><%= link_to "Help", 'help_path' %></li> <li><%= link_to "Log in", '#' %></li> </ul> </nav> </div> </header>
この中でも今回は、上記のroot_pathとhelp_pathに' 'がついていたことが原因みたいでした。このエラーが出た原因は、もともとあった'#'にroot_pathなどを入れたことで外し忘れていたみたいでした。
正しくはこちらになります。<li><%= link_to "Home", root_path %></li> <li><%= link_to "Help", help_path %></li>
因みに、app/views/layouts/_fotter.html.erbにも同じようなミスがあったので、上記のエラーが起こった方は確認してみると良いかもしれません。参照元
- 投稿日:2020-10-28T15:33:33+09:00
〇〇env系ツールをanyenvで一括管理する
はじめに
この記事は フューチャーAdvent Calendar 2020 の20日目の記事です。
環境構築に便利な〇〇env系ツールを、もっと便利に扱える
anyenv
に感動したので、ブログ化しました。開発言語のバージョン管理
複数プロジェクトに関わる場合、開発言語のバージョン管理は必須スキルです。
他の開発メンバーと利用バージョンを一致させなければ、フォーマッタ適用 → PRでの差分爆発が生じてレビュアーに袋叩きにされます。なので、各エンジニアはそれぞれの創意工夫により、開発言語のバージョン管理問題を解決しています。
私の場合、環境構築ポリシーとして
- ローカル環境への直ダウンロードは厳禁
- 環境構築は基本的にDockerを使うという方針を、ずっと貫いています。
...
スミマセン。強がりです。
貫けていませんでした。〇〇env の多用
コロナ影響で在宅勤務へ移行した結果、NWの問題によりDockerがうまく使えない状況が増え、仕方なく〇〇env系ツールの利用を開始しました。
インストールした〇〇env系ツールは
- PJ開発はメインでgoを使う → goenv
- 環境Aはpythonのみ動く → pyenv
- 環境Bはrubyのみ動く → rbenv
- AWSのMFA(多要素認証)でet-otpを使う → jenvというもので、開発作業で新しい言語が必要になるたびに、対応するツール1つ1つ追加していました。
これらは同じコマンド操作で設定可能なため、ストレスになるのはパッケージのダウンロード時間くらいだと思っていましたが、知らぬ間に開発環境汚染が進んでいました。
bash_profileが汚れていた
担当業務で Vue.js のコードに触れる機会があり、新たに
nodenv
をインストールしようとしたところ
- 〇〇env系ツールの環境構築って、いっつも同じような環境変数を追加しているな
- bash_profileのメンテしてたっけ?ということに気づき、cat ~/.bash_profile すると、↓こんな感じになっていました
... # goenv export GOENV_ROOT=$HOME/.goenv export PATH=$GOENV_ROOT/bin:$PATH eval "$(goenv init -)" # pyenv export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" # jenv export JENV_ROOT=$HOME/.jenv export PATH="$HOME/.jenv/bin:$PATH" eval "$(jenv init -)" (rbenv, nodenv などの設定が続く...) ...あれ?
開発環境が汚れないよう注意していたはずなのに
所々で微妙な違いがあり、綺麗な状態とは言い難い...〇〇env系ツールが増えるごとに
bash_profileに追記し続けるのを止めたい...
anyenv が便利そう!
anyenvを使って綺麗にする
anyenv自体の説明前に、このツールを使うと何が綺麗になるか?から説明します。
すでにインストール済みのgoenv, pyenvなどはanyenv経由での再設定が必要になりますが、それを乗り越えれば、bash_profile に必要な
〇〇env系ツールの記述
は、以下のみで十分となります。将来的に新しい 〇〇env が必要になった場合でも、bash_profile への追記は不要です。... # anyenv eval "$(anyenv init -)" ...goenv, jenvごとにPATHを設定 & initする煩わしい記述から解放され、かつ、操作方法は従来の〇〇env系コマンドを利用可能なので、開発環境汚染を少しでも減らしたいエンジニアであれば、このツールを使わない理由は無いと思います。
anyenvとは?
anyenv - All in one for **env
This is a simple wrapper for rbenv style environment managers. You don't have to git clone or modify your shell profile for each **env anymore if you install anyenv.
https://github.com/anyenv/anyenv#anyenv---all-in-one-for-env
端的に言うと、複数の〇〇envを一括管理できる便利ツールです。
執筆時点(2020.12.10)では、以下〇〇envパッケージがanyenvでは利用可能です。
有名どころは網羅しているので、多くの開発プロジェクトで導入可能だと思います。$ anyenv install -l Renv #R crenv #Crystal denv #D erlenv #Erlang exenv #Elixir goenv #Go hsenv #Haskell jenv #Java jlenv #Julia luaenv #Lua nodenv #Node.js phpenv #PHP plenv #Perl pyenv #Python rbenv #Ruby sbtenv #Sbt scalaenv #Scala swiftenv #Swift tfenv #terraform上記から欲しい言語をインストールすれば、あとはいつも通りの〇〇env操作コマンドで環境構築可能です。
anyenvのインストール手順
macの場合
Homebrewを利用します。
$ brew install anyenv $ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile $ exec $SHELL -l $ anyenv install --init # enter "y"Linux環境の場合
GitHubから直接引っ張ってきます。
$ git clone https://github.com/anyenv/anyenv ~/.anyenv $ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile $ exec $SHELL -l $ anyenv install --init # enter "y"最後に
$ anyenv install 〇〇env
で欲しいパッケージを取得すれば、これまで通りの〇〇envコマンドが利用できます。ex) node.jsのv15.0.1が欲しい場合
anyenvを利用し、nodenvを取得します。
$ anyenv install nodenv $ exec $SHELL -l $ anyenv versions nodenv: Warning: no Node detected on the system次は、nodenvでv15.0.1を取得します。
$ nodenv install 15.0.1 $ nodenv global(local) 15.0.1 $ node -v v15.0.1以上により、Node.js:v15.0.1 が利用可能となりました。
私の開発では goenv, pyenv, jenv, nodenv が必須なので、以下の設定を入れています。
$ anyenv versions
により、各envの設定状況が一覧できます。$ anyenv versions goenv: system 1.XX.0 * 1.YY.0 (set by /Users/<username>/.anyenv/envs/goenv/version) jenv: system * XX.0 (set by /Users/<username>/.anyenv/envs/jenv/version) nodenv: system * XX.0 (set by /Users/<username>/.anyenv/envs/nodenv/version) pyenv: system XX.0 * YY.0 (set by /Users/<username>/.anyenv/envs/pyenv/version)anyenvインストール以前に設定したgoenvやpyenvの環境変数が残っている場合は、bash_profileから削除することも忘れないようご注意ください。
まとめ
- 環境変数、
echo 'export hogehoge"' >> ~/.bash_profile
で追加したまま放置していませんか- 複数の〇〇env系ツールを使っているなら、anyenvの利用がオススメ
- anyenvでbash_profileがスッキリ
- 投稿日:2020-10-28T14:42:30+09:00
variable and method
variable
お題
受け取った引数ARGV[0]をnameという変数(variable)に代入してそれを打ち出すcodeを書け.
> ruby name_variable.rb Rudy Rudy簡単な解説
rubyの変数は型宣言の必要性がありません.文脈に合わせて適当に型が定められます.イコールで代入されます.
name = 'Rudy'なんかです.
詳しい解法
> ruby name_variable.rb Rudyとしましょう.
ruby: No such file or directory -- name_variable.rb (LoadError)というエラーが返ってきますよね.そんなファイルないよって.なら作ります.
> emacs name_variable.rbとしてemacsを起動して
p "Rudy"と打ち込んでsaveしましょう.
> ruby name_variable.rb Rudy "Rudy"
類題
さてこの後,
- nameに代入してRudyと打ち出すようにrefactoringしてください.
- ARGV[0]を受け取って,自分の名前を返すようにrefactoringしてください
p "Rudy"
method
お題
> ruby hello_method.rb Rudy Hell Rudy.と返すhello methodを作りなさい.
解説
Rubyではfunctionやprocedureなどのまとまりはmethodを定義(definition)することになります.methodは0個以上の引数(argument)を取ることができます.例えば次の通りです.
def hello(name) p name end解法
> ruby hello_method.rb Rudyとして見ましょう.もちろん動きませんよね.emacsでhello_method.rbを編集します.
> emacs hello_method.rb何ですが,methodの中身ではなく呼び出す方から考えます.普通に,
hello(name)と打ち込んで動かして見てください.
> ruby hello_method.rb Rudy hello_method.rb:1:in `<main>': undefined local variable or method `name' for main:Object (NameError)というエラーが返ってきたはずです.nameという変数やmethodがundefineやと怒られています.そこで今まで学んできたのを思い出して,nameにARGV[0]を代入します.
name = ARGV[0] hello(name)次のerrorは
> ruby hello_method.rb Rudy hello_method.rb:2:in `<main>': undefined method `hello' for main:Object (NoMethodError)でhelloっていうmethodがないよですね.
類題
先の解法を参照してhello メソッドを完成させてください.
name = ARGV[0] hello(name)ここで学んだこと
- ruby
- variable
- method
- argument
TDD
codingの最終目標
こういうcodingの仕方はTDD(Test Driven Development:テスト駆動開発)と呼ばれています.
- テストを作る
- エラーを出す(red)
- エラーをなくす(green)
- codeを綺麗にする(refactoring)
です.codingの最終目標は
clean code that works動く綺麗なコードを作ることです.順番は,まず動かして,それからこそこそと綺麗にするです.えっと,もし,あなたが,
- codeを書くまえに設計すべき
- コピペは悪
なんていう,マントラを信じているならこのprogramming styleを提唱し始めたKent Beckの文章を載せておきます.よーーく心に刻んでください.
もしあなたがプログラミング嫌いならば,少し心が晴れると思いますよ.俺のせいじゃないって.
clean code that works
TDD by Example (Kent Beck) p.13
目指すのは,動作するきれいなコードだ(このRon Jeffriesの簡潔な表現は素晴らしい).動作するきれいなコードは,偉大なプログラマでもすぐには書けないことがあるし,普通のプログラマならなおさらだ(私もそうだ).
=ここは分割統治しよう.=
各個撃破だぜ,ベイビー.最初に「動作する」に取り組み,その後で「きれいな」に取り組む.この方法はアーキテクチャ駆動とは正反対だ.アーキテクチャ駆動は「きれいなコード」に最初に取り組み,そのうえで苦心してあちこち設計の辻褄を合わせながらどうにか「動作する」を実現させる.TDD by Example (Kent Beck) p.11
The goal is clean code that works(thenks to Ron Jeffries for this pithy summary).Clean code that works is out of the reach of even the best programmerssome of the time,and out of the reach of most programmers(like me)most of the time.Divide and conquer, baby.First we'll solve the "that works" part of the problem.Then we'll solve the "clean code" part.This is the opposite of architecture-driven development,where you solve "clean code" first,then scramble around trying to integrate into the design the things you learn as you solve the "that works" problem.
phases and speed
TDD by Example (Kent Beck) p.30
グリーンバーを出す小さなステップはどんなものだろうか.Dollarクラスを丸ごとコピーして,DollarをFrancに書き換えるのはどうだろう.
ちょっと待った.これで唾棄すべき糞コードの出来上がりだとあざ笑う声が聞こえる.その声は続けて言う.コピー&ペーストによる再利用は抽象化の敗北であり,きれいな設計を殺すと.
イラっとしただろうか.なら深呼吸だ.鼻から息を吸い込んで,3秒止めて口から吐き出す.オーケー?さて,サイクルにはフェーズがあることを思い出してほしい(中には数秒で通り過ぎるものもあるが,フェーズはフェーズだ).
- テストを書く.
- コンパイラを通す.
- テストを走らせ,失敗を確認する.
- テストを通す.
- 重複を排除する.
各フェーズにはフェーズなりの目的と解決法があり,価値観も異なっている.最初の3つのフェーズはなるべく速く通過して,新しい機能がどの状態にあるのかわかるところまで行きたい.そこにたどり着くためには,どのような罪をおかしてもよい.その短い時間だけは,速度が設計よりも重要だからだ.
1つ心配なのは,私がここに書いていることが,良い設計の原則を無視してよいという免罪符になってしまうことだ.チームに対して「Kent Beckが設計なんてどうでもいいって書いてたよ」などと言い始めるのは,ちょっと待ってほしい.サイクルはまだ終わっていない.4つ足のアーロンチェアは倒れる.最初の4つのステップは,5つ目がなければ無意味だ.正しい設計を,正しいタイミングで行う.動かしてから,正しくする.
ここまで言っておけば安心だろう.これで読者の皆さんは重複を排除するまで誰にもコードを見せないはずだ(ただし,ペアプロ相手は除く)
TDD by Example (Kent Beck) p.23
What short step will get us to a green bar?Copying the Dollar code and replacing Dollar with Franc.
Stop. Hold on.I can hear the aesthetically inclined among you sneering and spitting.Copy-and-paste reuse?The death of abstraction?The killer of clean design?
If you're upset, take a cleanthing breath.In through the nose … hold it 1, 2, 3… out through the mouth.There. Remember, our cycle has different phases(they go by quickly, often in seconds, but they are phases.):
- Write a test.
- Make it compile.
- Run it to see that it fails.
- Make it run.
- Remove duplication.(Make it right.)
The different phases have different purposes.They call for different styles of solution, different aesthetic viewpoints.The first three phases need to go by quickly,so we get to a known state with the new functionality.We can commit any number of sins to get there,because speed trumps design,just for that brief moment.
Now I'm worried.I've given you a license to abandon all the principles of good design.Off you go to your teams –"Kent says all that design stuff doesn't matter."Halt. The cycle is not complete.A four-legged Aeron chair falls over.The first four steps of the cycle won't work without the fifth.Good design at good times.Make it run, make it right.
There, I feel better.Now I'm sure you won't show anyone except your partner your codeuntil you've removed the duplication.Where were we?Ah, yes.Violating all the tenets of good design in the interest of speed(penance for our sin will occupy the next several chapters).
おまけ
言語は英語から
これをmethodにしたら,
def func(hoge) puts "Hello #{hoge}." end hoho = ARGV[0] func(hoho)これを動かしてみましょう.
> ruby hello.rb bobとちゃんと動きます.これでは何をしているのかわからないので,コメントをつけましょう.
# method: func # input: hoge is a name # output: puts greetings # return: nil def func(hoge) puts "Hello #{hoge}." end honya = ARGV[0] # get hoho from argv func(honya) # call hello with a name honya英語でしっかりとコメントが書ければ世界中に通用するcodeが書ける…んでしょうかね?コメントをぐちゃぐちゃ書くんじゃなくて,もっとわかりやすい名前(method名,変数名)にしたくなるでしょう?
def puts_hello name puts "Hello #{name}." end name = ARGV[0] puts_hello nameこっちの方が短くてスッキリしていて圧倒的にいいでしょ? 適切な英単語を使えば,要らん説明が省けます.これが言語は英語からという意味です.
長くなったら,隠せ
もしoptionのnameを打つのを忘れたら,問い合わせてくれると,user interfaceという感じがもっとするでしょう?
name = ARGV[0] if name == nil puts "What\'s your name?" name = gets.chomp endというのをname=の下につけましょう[1].ちょっと動かして見ましょう.
> ruby hello.rb意図通りに動いていますか? でもmain loopが長くなってきちゃいました.そこで,これもmethodに切り出します.領域を指定して(C-spaceで先頭を指定して移動),C-wでcut, 移動してC-yでyankです.
def gets_name name = ARGV[0] if name == nil puts "What\'s your name?" name = gets.chomp end return name end name = gets_nameこの時,領域を指定してM-x indent-regionとしてください.あるいはC-x TAB.これだけでもだいぶ読みやすくなったでしょ?
もっとできます.main loopにcursorを持って行って,'C-c @ C-l'と打ってみてください.
def puts_hello name...end def gets_name...end name = gets_name puts_hello nameこれがoutlineによるtoggle表示からきたすごいメタファなんですよ.何をしているのか知らなくていい部分は隠してしまおうというのが,methodに切り分ける理由なんです.
今日の教え- editor -
ここで示した優秀なeditorのmeritは納得いただけましたでしょうか?必須操作を少しだけリストアップしておくと,
- editのkey-bind
- syntax high_lighting
- code hiding, show
- block copy, 移動
- query-replace
- shellとの連携
- source ~/git_hub/ruby_docs/chart_style_ruby/c2_name_method_hello.org
- 投稿日:2020-10-28T14:42:30+09:00
チャート式ruby-II(variable and method)
variable
お題
受け取った引数ARGV[0]をnameという変数(variable)に代入してそれを打ち出すcodeを書け.
> ruby name_variable.rb Rudy Rudy簡単な解説
rubyの変数は型宣言の必要性がありません.文脈に合わせて適当に型が定められます.イコールで代入されます.
name = 'Rudy'なんかです.
詳しい解法
> ruby name_variable.rb Rudyとしましょう.
ruby: No such file or directory -- name_variable.rb (LoadError)というエラーが返ってきますよね.そんなファイルないよって.なら作ります.
> emacs name_variable.rbとしてemacsを起動して
p "Rudy"と打ち込んでsaveしましょう.
> ruby name_variable.rb Rudy "Rudy"
類題
さてこの後,
- nameに代入してRudyと打ち出すようにrefactoringしてください.
- ARGV[0]を受け取って,自分の名前を返すようにrefactoringしてください
p "Rudy"
method
お題
> ruby hello_method.rb Rudy Hell Rudy.と返すhello methodを作りなさい.
解説
Rubyではfunctionやprocedureなどのまとまりはmethodを定義(definition)することになります.methodは0個以上の引数(argument)を取ることができます.例えば次の通りです.
def hello(name) p name end解法
> ruby hello_method.rb Rudyとして見ましょう.もちろん動きませんよね.emacsでhello_method.rbを編集します.
> emacs hello_method.rb何ですが,methodの中身ではなく呼び出す方から考えます.普通に,
hello(name)と打ち込んで動かして見てください.
> ruby hello_method.rb Rudy hello_method.rb:1:in `<main>': undefined local variable or method `name' for main:Object (NameError)というエラーが返ってきたはずです.nameという変数やmethodがundefineやと怒られています.そこで今まで学んできたのを思い出して,nameにARGV[0]を代入します.
name = ARGV[0] hello(name)次のerrorは
> ruby hello_method.rb Rudy hello_method.rb:2:in `<main>': undefined method `hello' for main:Object (NoMethodError)でhelloっていうmethodがないよですね.
類題
先の解法を参照してhello メソッドを完成させてください.
name = ARGV[0] hello(name)ここで学んだこと
- ruby
- variable
- method
- argument
TDD
codingの最終目標
こういうcodingの仕方はTDD(Test Driven Development:テスト駆動開発)と呼ばれています.
- テストを作る
- エラーを出す(red)
- エラーをなくす(green)
- codeを綺麗にする(refactoring)
です.codingの最終目標は
clean code that works動く綺麗なコードを作ることです.順番は,まず動かして,それからこそこそと綺麗にするです.えっと,もし,あなたが,
- codeを書くまえに設計すべき
- コピペは悪
なんていう,マントラを信じているならこのprogramming styleを提唱し始めたKent Beckの文章を載せておきます.よーーく心に刻んでください.
もしあなたがプログラミング嫌いならば,少し心が晴れると思いますよ.俺のせいじゃないって.
clean code that works
TDD by Example (Kent Beck) p.13
目指すのは,動作するきれいなコードだ(このRon Jeffriesの簡潔な表現は素晴らしい).動作するきれいなコードは,偉大なプログラマでもすぐには書けないことがあるし,普通のプログラマならなおさらだ(私もそうだ).
=ここは分割統治しよう.=
各個撃破だぜ,ベイビー.最初に「動作する」に取り組み,その後で「きれいな」に取り組む.この方法はアーキテクチャ駆動とは正反対だ.アーキテクチャ駆動は「きれいなコード」に最初に取り組み,そのうえで苦心してあちこち設計の辻褄を合わせながらどうにか「動作する」を実現させる.TDD by Example (Kent Beck) p.11
The goal is clean code that works(thenks to Ron Jeffries for this pithy summary).Clean code that works is out of the reach of even the best programmerssome of the time,and out of the reach of most programmers(like me)most of the time.Divide and conquer, baby.First we'll solve the "that works" part of the problem.Then we'll solve the "clean code" part.This is the opposite of architecture-driven development,where you solve "clean code" first,then scramble around trying to integrate into the design the things you learn as you solve the "that works" problem.
phases and speed
TDD by Example (Kent Beck) p.30
グリーンバーを出す小さなステップはどんなものだろうか.Dollarクラスを丸ごとコピーして,DollarをFrancに書き換えるのはどうだろう.
ちょっと待った.これで唾棄すべき糞コードの出来上がりだとあざ笑う声が聞こえる.その声は続けて言う.コピー&ペーストによる再利用は抽象化の敗北であり,きれいな設計を殺すと.
イラっとしただろうか.なら深呼吸だ.鼻から息を吸い込んで,3秒止めて口から吐き出す.オーケー?さて,サイクルにはフェーズがあることを思い出してほしい(中には数秒で通り過ぎるものもあるが,フェーズはフェーズだ).
- テストを書く.
- コンパイラを通す.
- テストを走らせ,失敗を確認する.
- テストを通す.
- 重複を排除する.
各フェーズにはフェーズなりの目的と解決法があり,価値観も異なっている.最初の3つのフェーズはなるべく速く通過して,新しい機能がどの状態にあるのかわかるところまで行きたい.そこにたどり着くためには,どのような罪をおかしてもよい.その短い時間だけは,速度が設計よりも重要だからだ.
1つ心配なのは,私がここに書いていることが,良い設計の原則を無視してよいという免罪符になってしまうことだ.チームに対して「Kent Beckが設計なんてどうでもいいって書いてたよ」などと言い始めるのは,ちょっと待ってほしい.サイクルはまだ終わっていない.4つ足のアーロンチェアは倒れる.最初の4つのステップは,5つ目がなければ無意味だ.正しい設計を,正しいタイミングで行う.動かしてから,正しくする.
ここまで言っておけば安心だろう.これで読者の皆さんは重複を排除するまで誰にもコードを見せないはずだ(ただし,ペアプロ相手は除く)
TDD by Example (Kent Beck) p.23
What short step will get us to a green bar?Copying the Dollar code and replacing Dollar with Franc.
Stop. Hold on.I can hear the aesthetically inclined among you sneering and spitting.Copy-and-paste reuse?The death of abstraction?The killer of clean design?
If you're upset, take a cleanthing breath.In through the nose … hold it 1, 2, 3… out through the mouth.There. Remember, our cycle has different phases(they go by quickly, often in seconds, but they are phases.):
- Write a test.
- Make it compile.
- Run it to see that it fails.
- Make it run.
- Remove duplication.(Make it right.)
The different phases have different purposes.They call for different styles of solution, different aesthetic viewpoints.The first three phases need to go by quickly,so we get to a known state with the new functionality.We can commit any number of sins to get there,because speed trumps design,just for that brief moment.
Now I'm worried.I've given you a license to abandon all the principles of good design.Off you go to your teams –"Kent says all that design stuff doesn't matter."Halt. The cycle is not complete.A four-legged Aeron chair falls over.The first four steps of the cycle won't work without the fifth.Good design at good times.Make it run, make it right.
There, I feel better.Now I'm sure you won't show anyone except your partner your codeuntil you've removed the duplication.Where were we?Ah, yes.Violating all the tenets of good design in the interest of speed(penance for our sin will occupy the next several chapters).
おまけ
言語は英語から
これをmethodにしたら,
def func(hoge) puts "Hello #{hoge}." end hoho = ARGV[0] func(hoho)これを動かしてみましょう.
> ruby hello.rb bobとちゃんと動きます.これでは何をしているのかわからないので,コメントをつけましょう.
# method: func # input: hoge is a name # output: puts greetings # return: nil def func(hoge) puts "Hello #{hoge}." end honya = ARGV[0] # get hoho from argv func(honya) # call hello with a name honya英語でしっかりとコメントが書ければ世界中に通用するcodeが書ける…んでしょうかね?コメントをぐちゃぐちゃ書くんじゃなくて,もっとわかりやすい名前(method名,変数名)にしたくなるでしょう?
def puts_hello name puts "Hello #{name}." end name = ARGV[0] puts_hello nameこっちの方が短くてスッキリしていて圧倒的にいいでしょ? 適切な英単語を使えば,要らん説明が省けます.これが言語は英語からという意味です.
長くなったら,隠せ
もしoptionのnameを打つのを忘れたら,問い合わせてくれると,user interfaceという感じがもっとするでしょう?
name = ARGV[0] if name == nil puts "What\'s your name?" name = gets.chomp endというのをname=の下につけましょう[1].ちょっと動かして見ましょう.
> ruby hello.rb意図通りに動いていますか? でもmain loopが長くなってきちゃいました.そこで,これもmethodに切り出します.領域を指定して(C-spaceで先頭を指定して移動),C-wでcut, 移動してC-yでyankです.
def gets_name name = ARGV[0] if name == nil puts "What\'s your name?" name = gets.chomp end return name end name = gets_nameこの時,領域を指定してM-x indent-regionとしてください.あるいはC-x TAB.これだけでもだいぶ読みやすくなったでしょ?
もっとできます.main loopにcursorを持って行って,'C-c @ C-l'と打ってみてください.
def puts_hello name...end def gets_name...end name = gets_name puts_hello nameこれがoutlineによるtoggle表示からきたすごいメタファなんですよ.何をしているのか知らなくていい部分は隠してしまおうというのが,methodに切り分ける理由なんです.
今日の教え- editor -
ここで示した優秀なeditorのmeritは納得いただけましたでしょうか?必須操作を少しだけリストアップしておくと,
- editのkey-bind
- syntax high_lighting
- code hiding, show
- block copy, 移動
- query-replace
- shellとの連携
- source ~/git_hub/ruby_docs/chart_style_ruby/./c2_name_method_hello.org
- 投稿日:2020-10-28T13:37:48+09:00
Ruby設定3 Rubocop
RuboCop
PATH
(m・_・bp) 18:16 ~/Desktop/vsnote2.0/ruby/lib/rubybook_2 % which rubocop /Users/uekiyoshihiro/.rbenv/shims/rubocop
RuboCopの導入
ruby-style-guide/README.ja.md at japanese · fortissimo1997/ruby-style-guide
# グローバルインストール $ gem install rubocop # インストール確認 $ rubocop -v # インストール場所確認 $ which rubocop /Users/myname/.rbenv/shims/rubocopRubocopの使用とオプション
$ rubocop # 自動修正(--auto-correctでもOK) $ rubocop -a # 違反した項目をすべて無効とする設定ファイル(.rubocop_todo.yml)が生成される やらなくてもいいかな $ rubocop --auto-gen-configRailsの設定に対応する
Gemのインストール
$ cd <プロジェクトルート> #プロジェクトルートに移動 $ gem install rubocop-performance #2つをインストール $ gem install rubocop-rails設定ファイルを新しく作成する
$ cd <プロジェクトルート> #プロジェクトルートに移動 $ touch .rubocop.yml #設定ファイルを新規作成 $ curl https://raw.githubusercontent.com/rails/rails/master/.rubocop.yml > .rubocop.yml #rails本家のコード規約をダウンロードして.rubocop.ymlファイルへ出力.rubocop.ymlの中身
require: - rubocop-performance - rubocop-rails AllCops: TargetRubyVersion: 2.5 # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop # to ignore them, so only the ones explicitly set in this file are enabled. DisabledByDefault: true Exclude: - '**/tmp/**/*' - '**/templates/**/*' - '**/vendor/**/*' - 'actionpack/lib/action_dispatch/journey/parser.rb' - 'railties/test/fixtures/tmp/**/*' - 'actionmailbox/test/dummy/**/*' - 'actiontext/test/dummy/**/*' - '**/node_modules/**/*' Performance: Exclude: - '**/test/**/*' # Prefer assert_not over assert ! Rails/AssertNot: Include: - '**/test/**/*' # Prefer assert_not_x over refute_x Rails/RefuteMethods: Include: - '**/test/**/*' Rails/IndexBy: Enabled: true Rails/IndexWith: Enabled: true # Prefer &&/|| over and/or. Style/AndOr: Enabled: true # Align `when` with `case`. Layout/CaseIndentation: Enabled: true Layout/ClosingHeredocIndentation: Enabled: true # Align comments with method definitions. Layout/CommentIndentation: Enabled: true Layout/ElseAlignment: Enabled: true # Align `end` with the matching keyword or starting expression except for # assignments, where it should be aligned with the LHS. Layout/EndAlignment: Enabled: true EnforcedStyleAlignWith: variable AutoCorrect: true Layout/EmptyLineAfterMagicComment: Enabled: true Layout/EmptyLinesAroundAccessModifier: Enabled: true EnforcedStyle: only_before Layout/EmptyLinesAroundBlockBody: Enabled: true # In a regular class definition, no empty lines around the body. Layout/EmptyLinesAroundClassBody: Enabled: true # In a regular method definition, no empty lines around the body. Layout/EmptyLinesAroundMethodBody: Enabled: true # In a regular module definition, no empty lines around the body. Layout/EmptyLinesAroundModuleBody: Enabled: true # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }. Style/HashSyntax: Enabled: true Layout/FirstArgumentIndentation: Enabled: true # Method definitions after `private` or `protected` isolated calls need one # extra level of indentation. Layout/IndentationConsistency: Enabled: true EnforcedStyle: indented_internal_methods # Two spaces, no tabs (for indentation). Layout/IndentationWidth: Enabled: true Layout/LeadingCommentSpace: Enabled: true Layout/SpaceAfterColon: Enabled: true Layout/SpaceAfterComma: Enabled: true Layout/SpaceAfterSemicolon: Enabled: true Layout/SpaceAroundEqualsInParameterDefault: Enabled: true Layout/SpaceAroundKeyword: Enabled: true Layout/SpaceBeforeComma: Enabled: true Layout/SpaceBeforeComment: Enabled: true Layout/SpaceBeforeFirstArg: Enabled: true Style/DefWithParentheses: Enabled: true # Defining a method with parameters needs parentheses. Style/MethodDefParentheses: Enabled: true Style/FrozenStringLiteralComment: Enabled: true EnforcedStyle: always Exclude: - 'actionview/test/**/*.builder' - 'actionview/test/**/*.ruby' - 'actionpack/test/**/*.builder' - 'actionpack/test/**/*.ruby' - 'activestorage/db/migrate/**/*.rb' - 'activestorage/db/update_migrate/**/*.rb' - 'actionmailbox/db/migrate/**/*.rb' - 'actiontext/db/migrate/**/*.rb' Style/RedundantFreeze: Enabled: true # Use `foo {}` not `foo{}`. Layout/SpaceBeforeBlockBraces: Enabled: true # Use `foo { bar }` not `foo {bar}`. Layout/SpaceInsideBlockBraces: Enabled: true EnforcedStyleForEmptyBraces: space # Use `{ a: 1 }` not `{a:1}`. Layout/SpaceInsideHashLiteralBraces: Enabled: true Layout/SpaceInsideParens: Enabled: true # Check quotes usage according to lint rule below. Style/StringLiterals: Enabled: true EnforcedStyle: double_quotes # Detect hard tabs, no hard tabs. Layout/IndentationStyle: Enabled: true # Empty lines should not have any spaces. Layout/TrailingEmptyLines: Enabled: true # No trailing whitespace. Layout/TrailingWhitespace: Enabled: true # Use quotes for string literals when they are enough. Style/RedundantPercentQ: Enabled: true Lint/AmbiguousOperator: Enabled: true Lint/AmbiguousRegexpLiteral: Enabled: true Lint/ErbNewArguments: Enabled: true # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg. Lint/RequireParentheses: Enabled: true Lint/ShadowingOuterLocalVariable: Enabled: true Lint/RedundantStringCoercion: Enabled: true Lint/UriEscapeUnescape: Enabled: true Lint/UselessAssignment: Enabled: true Lint/DeprecatedClassMethods: Enabled: true Style/ParenthesesAroundCondition: Enabled: true Style/HashTransformKeys: Enabled: true Style/HashTransformValues: Enabled: true Style/RedundantBegin: Enabled: true Style/RedundantReturn: Enabled: true AllowMultipleReturnValues: true Style/Semicolon: Enabled: true AllowAsExpressionSeparator: true # Prefer Foo.method over Foo::method Style/ColonMethodCall: Enabled: true Style/TrivialAccessors: Enabled: true Performance/FlatMap: Enabled: true Performance/RedundantMerge: Enabled: true Performance/StartWith: Enabled: true Performance/EndWith: Enabled: true Performance/RegexpMatch: Enabled: true Performance/ReverseEach: Enabled: true Performance/UnfreezeString: Enabled: true Performance/DeletePrefix: Enabled: true Performance/DeleteSuffix: Enabled: truegithooksの設定
【Ruby on Rails】rubocop と pre-commit を利用して git commit 時にコーディングチェックを行う - きゃまなかのブログ
- 投稿日:2020-10-28T13:33:53+09:00
Ruby設定2
gemとは?
- 決まったフォーマットで提供されるRuby言語用のライブラリを「gem」と呼びます。
- 「gem」には例えば以下のようなものがある。
- Rails(Webフレームワーク)
- Sinatra(Webフレームワーク)
- omniauth(認証機能)
- unicorn(アプリケーションサーバ)
- Rspec(テストフレームワーク) ...etc
- PerlでいうCPAN、phpでいうpear等にあたる
Rubygemsとは
- yumやaptと似た、gem専用のパッケージ管理システム。
- 以下サイトにてgemの情報公開、提供を行っている。 https://rubygems.org/
Bundlerとはなんぞや
- gemは以下のように個別に手動インストールする事が可能です。
- gem install "sinatra"
- gem install "unicorn"
- gem install "omniauth"
- しかし、様々なgem(ライブラリ)を組み合わせて使っていると「gemAのver1とgemBのVer2はうまく動くけど、最新バージョン同士だとうまく動かない。」という互換性の問題が出てくる場合があります。
- また、複数人、複数環境で開発を行う場合は、各環境で使うライブラリの名前、バージョンを合わせる必要があります。
- こういった場合に、gem同士の互換性を保ちながら各gemの導入、管理を行ってくれるのがBundlerです。
- Gemfileというファイルにインストールしたいgemを記述し、それを元にbundlerを使ってインストールを行います。
- bundler本体以外のgemは基本的にbundler経由でインストールを行うのがおすすめです。
Bundlerのインストールの仕方
- Bundlerのインストール
- Bundlerもgemの1つです。手動ダウンロードしましょう
- gem install bundler
- 導入後はバージョンが表示される事を確認してください。
- bundler -v
Bundlerの使い方
- Gemfileの作成
- bundle init
- 上記実行するとGemfileという雛形ファイルが作成されます
- 使用したいgemをGemfileに記述する
- Gemfileを編集する
- vi Gemfile
- Gemfileの先頭に、インストール元はrubygemsですよ、と宣言を行います。
- source "rubygems"
- 続けてインストールしたいgemを記述します
- gem "sinatra"
- gem "unicorn"
- gem "omniauth"
- gemの指定の際に、バージョンの指定も可能です
- gem 'rails', "~> 4.2.4"
- Gemfileにリスト化したgemを一括インストール
- 一括インストール
- bundle install --path vendor/bundle
- --pathでインストール先を指定可能。一度でも--path指定でインストールしたら、次回以降はpath指定無しでbundle installを行っても同じpathが選択されます。
- この時、インストールしたgemの名前とバージョンを記載した「gemfile.lock」というファイルが作成されます。
- インストールしたgemをプログラムソース上でロード
- まずソース上でrubygemsをrequireします。
- require "rubygems"
- 以下のように記述するとインストールした内容からrequireを行うように(指定無しだとシステム最新のgemを使ってしまいます)
- require "bundler/setup"
- プログラムを実行する際は、最初にbundle execを実行します。(指定無しだと互換性を考慮せずにシステム最新のgemを使ってしまう)
- bundle exec ruby foo.rb
参考
- Rubygemsのススメ | Rubyに慣れていない初心者さんへ http://qiita.com/sumyapp/items/5ec58bf3567e557c24d7
- Bundler概要 http://qiita.com/hisonl/items/162f70e612e8e96dba50
- Bundlerとは http://shokai.org/blog/archives/7262
GemコマンドとBundlerの基礎 - BlueTechNote
Gemコマンドを使用
$ gem install $ gem update $ gem uninstallbundler
- Bundler をインストールする
- Gemfile にインストールするGem を書く
- bundle installコマンドでインストールする
- bundle updateコマンドでGemをバージョンアップする ```console - Bundler をインストールする (m・_・bp) 17:50 ~/Desktop/vsnote2.0/ruby % gem install bundler Fetching bundler-2.1.4.gem Successfully installed bundler-2.1.4 Parsing documentation for bundler-2.1.4 Installing ri documentation for bundler-2.1.4 Done installing documentation for bundler after 2 seconds 1 gem installed
- Gemfile にインストールするGem を書く
(m・_・bp) 17:51 ~/Desktop/vsnote2.0/ruby % bundle init
Writing new Gemfile to /Users/uekiyoshihiro/Desktop/vsnote2.0/ruby/Gemfile
- bundle installコマンドでインストールする
(m・・bp) 17:53 ~/Desktop/vsnote2.0/ruby % bundle install
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
Using bundler 2.1.4
Fetching coderay 1.1.2
Installing coderay 1.1.2
Fetching methodsource 1.0.0
Installing method_source 1.0.0
Fetching pry 0.13.1
Installing pry 0.13.1
Bundle complete! 1 Gemfile dependency, 4 gems now installed.
Usebundle info [gemname]
to see where a bundled gem is installed.
- bundle updateコマンドでGemをバージョンアップする
(m・・bp) 17:58 ~/Desktop/vsnote2.0/ruby % bundle update
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
Using bundler 2.1.4
Using coderay 1.1.2
Using methodsource 1.0.0
Using pry 0.13.1
Bundle updated!
```よく使うコマンド集
$ bundle init #Gemfileを生成 $ bundle install #Gemfileに書かれたgemパッケージをインストール $ bundle exec #Bundlerでインストールされたgemパッケージを使用してコマンドを実行 $ bundle list #インストール済みのgemパッケージの一覧を表示 $ bundle update #インストール済みのgemパッケージのバージョンを更新
- 投稿日:2020-10-28T12:56:43+09:00
Ruby環境設定
初めに
Bundlerのインストールの仕方
- Bundlerのインストール
- Bundlerもgemの1つです。手動ダウンロードしましょう
- gem install bundler
- 導入後はバージョンが表示される事を確認してください。
- bundler -v
Bundlerの使い方
- Gemfileの作成
- bundle init
- 上記実行するとGemfileという雛形ファイルが作成されます
- 使用したいgemをGemfileに記述する
- Gemfileを編集する
- vi Gemfile
- Gemfileの先頭に、インストール元はrubygemsですよ、と宣言を行います。
- source "rubygems"
- 続けてインストールしたいgemを記述します
- gem "sinatra"
- gem "unicorn"
- gem "omniauth"
- gemの指定の際に、バージョンの指定も可能です
- gem 'rails', "~> 4.2.4"
- Gemfileにリスト化したgemを一括インストール
- 一括インストール
- bundle install --path vendor/bundle
- --pathでインストール先を指定可能。一度でも--path指定でインストールしたら、次回以降はpath指定無しでbundle installを行っても同じpathが選択されます。
- この時、インストールしたgemの名前とバージョンを記載した「gemfile.lock」というファイルが作成されます。
- インストールしたgemをプログラムソース上でロード
- まずソース上でrubygemsをrequireします。
- require "rubygems"
- 以下のように記述するとインストールした内容からrequireを行うように(指定無しだとシステム最新のgemを使ってしまいます)
- require "bundler/setup"
- プログラムを実行する際は、最初にbundle execを実行します。(指定無しだと互換性を考慮せずにシステム最新のgemを使ってしまう)
- bundle exec ruby foo.rb
参考
- Rubygemsのススメ | Rubyに慣れていない初心者さんへ http://qiita.com/sumyapp/items/5ec58bf3567e557c24d7
- Bundler概要 http://qiita.com/hisonl/items/162f70e612e8e96dba50
- Bundlerとは http://shokai.org/blog/archives/7262
確認
(m・_・bp) mbp-2 17:04 ~ % ruby -v ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]色々インストール
$ brew install openssl $ brew install readline $ brew install libyaml $ brew install autoconfruby-build
ruby-buildはrbenvのプラグインで、自動でrubyをビルドする。
$ brew update $ brew upgrade ruby-build $ ruby-build --version現在のバージョン確認
## .rbenvのinstall ```bash (m・_・bp) mbp-2 17:10 ~ % brew install rbenv ruby-build/etc/zprofileへの追記
(m・_・bp) mbp-2 17:12 ~ % cd /etc (m・_・bp) mbp-2 17:16 /etc % sudo cp zprofile zprofile.org /etc % sudo vi zprofile ############################rbenv PATH
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi export PATH="$HOME/.rbenv/bin:$PATH" eval "$(rbenv init -)" (m・_・bp) mbp-2 18:06 ~ % source /etc/zprofilerbenvのinstall確認
(m・_・bp) mbp-2 17:22 ~ % rbenv -v rbenv 1.1.2ruby-buildインストール,,,既にインストールしてた
(m・_・bp) mbp-2 17:35 ~ % brew install ruby-build Warning: ruby-build 20200401 is already installed and up-to-date To reinstall 20200401, run `brew reinstall ruby-build`rbenvで最新versionをinstall
(m・_・bp) mbp-2 17:22 ~ % rbenv versions * system (set by /Users/uekiyoshihiro/.rbenv/version)rbenvでインストール
Rubyの公式サイト
こちらのサイトをみて安定版の最新バージョンをインストール~ % rbenv install -l ~ % rbenv install 2.7.1 ~ % ruby -v ~ % rbenv install 2.6.5rubyのバージョンを切り替える
バージョン切り替えには、ディレクトリのみの設定orデフォ設定の2種類がある。
$ rbenv local <バージョン> # 実行したディレクトリ配下で使うrubyのバージョンを変更 # 指定バージョンの .ruby-version が作成される $ rbenv global <バージョン> # デフォルトで使うrubyのバージョンを変更 $ rbenv local --unset # ローカルバージョン指定の取消し上記の通り、アプリごとに異なるバージョンのrubyを利用したい場合は、各ディレクトリで
rbenv local
を実行して、rubyのバージョンを指定。ちなみにこれらのコマンドを実行すると、現在のディレクトリに 「.ruby-version」 というファイルが作成される。これは自動で使用するrubyのバージョンを変えるもの。
その他:openssl
opensslはhttpsを使用するためのパッケージ。
$ which openssl $ brew list openssl $ openssl version(m・_・bp) mbp-2 19:48 ~ % rbenv versions system 2.6.5 2.6.6 * 2.7.1 (set by /Users/uekiyoshihiro/.ruby-version)
(m・_・bp) 14:57 ~/Desktop/vsnote2.0/ruby/lib/rubybook_2 % gem install minitest -v 5.10.1 Fetching minitest-5.10.1.gem Successfully installed minitest-5.10.1 Parsing documentation for minitest-5.10.1 Installing ri documentation for minitest-5.10.1 Done installing documentation for minitest after 0 seconds 1 gem installed
- 投稿日:2020-10-28T12:56:43+09:00
Ruby設定1
初めに
確認
(m・_・bp) mbp-2 17:04 ~ % ruby -v ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]色々インストール
$ brew install openssl $ brew install readline $ brew install libyaml $ brew install autoconfruby-build
ruby-buildはrbenvのプラグインで、自動でrubyをビルドする。
$ brew update $ brew upgrade ruby-build $ ruby-build --version現在のバージョン確認
## .rbenvのinstall ```bash (m・_・bp) mbp-2 17:10 ~ % brew install rbenv ruby-build/etc/zprofileへの追記するために移動
(m・_・bp) mbp-2 17:12 ~ % cd /etc (m・_・bp) mbp-2 17:16 /etc % sudo cp zprofile zprofile.org #念のため予備を作っておく (m・_・bp) mbp-2 17:16 /etc % sudo vi zprofilerbenv PATH zprofileに下記の事を追記
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi export PATH="$HOME/.rbenv/bin:$PATH" eval "$(rbenv init -)" (m・_・bp) mbp-2 18:06 ~ % source /etc/zprofilerbenvのinstall確認
(m・_・bp) mbp-2 17:22 ~ % rbenv -v rbenv 1.1.2ruby-buildインストール,,,既にインストールしてた
(m・_・bp) mbp-2 17:35 ~ % brew install ruby-build Warning: ruby-build 20200401 is already installed and up-to-date To reinstall 20200401, run `brew reinstall ruby-build`rbenvで最新versionをinstall
(m・_・bp) mbp-2 17:22 ~ % rbenv versions * system (set by /Users/uekiyoshihiro/.rbenv/version)rbenvでインストール
Rubyの公式サイト
こちらのサイトをみて安定版の最新バージョンをインストール~ % rbenv install -l ~ % rbenv install 2.7.1 ~ % ruby -v ~ % rbenv install 2.6.5rubyのバージョンを切り替える
バージョン切り替えには、ディレクトリのみの設定orデフォ設定の2種類がある。
$ rbenv local <バージョン> # 実行したディレクトリ配下で使うrubyのバージョンを変更 # 指定バージョンの .ruby-version が作成される $ rbenv global <バージョン> # デフォルトで使うrubyのバージョンを変更 $ rbenv local --unset # ローカルバージョン指定の取消し上記の通り、アプリごとに異なるバージョンのrubyを利用したい場合は、各ディレクトリで
rbenv local
を実行して、rubyのバージョンを指定。ちなみにこれらのコマンドを実行すると、現在のディレクトリに 「.ruby-version」 というファイルが作成される。これは自動で使用するrubyのバージョンを変えるもの。
その他:openssl
opensslはhttpsを使用するためのパッケージ。
$ which openssl $ brew list openssl $ openssl version(m・_・bp) mbp-2 19:48 ~ % rbenv versions system 2.6.5 2.6.6 * 2.7.1 (set by /Users/uekiyoshihiro/.ruby-version)
(m・_・bp) 14:57 ~/Desktop/vsnote2.0/ruby/lib/rubybook_2 % gem install minitest -v 5.10.1 Fetching minitest-5.10.1.gem Successfully installed minitest-5.10.1 Parsing documentation for minitest-5.10.1 Installing ri documentation for minitest-5.10.1 Done installing documentation for minitest after 0 seconds 1 gem installed
- 投稿日:2020-10-28T12:36:45+09:00
Rails Tutorial 第4章学習編
Rails Tutorial 第4章で(。´・ω・)ん?って思ったところ
前提知識と復習でアウトプットしているからだと思いますが、
この章は特に(。´・ω・)ん?って思ったところはないです。
動画もテキストも非常に分かりやすかったです。Rails 第4章 簡単な内容のおさらい
第四章はRails風味のRubyです。こんなに分かりやすいオブジェクト指向は初めてです。
ProgateのPython、TECH::CAMPのRubyでも学習しましたが。。。
(゜-゜)う~ん オブジェクト指向それって美味しいの?って感じでした。よく説明に・・・全てのモノはオブジェクトです。
人も一つのオブジェクト、車も一つのオブジェクト
ジョンという人がいる。ジョンは人に属している。
人は職業・性別・年齢などの要素を持っている。。。
こんな内容に沿ってコードを書かされて(。´・ω・)ん?って感じになります。私の言葉でのオブジェクト指向を説明すると・・・
"文字列"があります。 オブジェクト指向で記述されていると、 "12345".length #文字をカウントするメソッドが使える。 "12345".to_i #文字列を整数に変換するメソッドが使える。 .lengthメソッド・.to_iメソッドを定義していないのに何で使えるの? ⇒ 答えはオブジェクト指向で書かれているからです。 まだ、(。´・ω・)ん?って感じですよね 実は"文字列"と書けば文字列と認識されていますが、 String.new("文字列")というコードの省略形です。 文字列(String)クラスのオブジェクト"文字列"を作りなさいという意味なんです。 予め文字列(String)クラスに様々なメソッドが用意されています。 String.new("")で生成したオブジェクトは文字列オブジェクトなので定義済みメソッドが使えるのです。 文字列クラスで.to_iメソッドが用意されているので、 新しく生成した文字列も.to_iなどの様々なメソッドが使えるという事です。 オブジェクト指向の最大の利点は、 文字列は必ず文字列オブジェクトとして生成する事で.to_iなどメソッドを共有出来きる事です。('ω')ノ 文字列クラスに新しいメソッドを追加すれば、全ての文字列オブジェクトで使用できるって事です。 Progateで学んだ時は(。´・ω・)ん?でしたが、今になって便利さが分かりました(´-ω-`)クラスと継承
"文字列"はStringクラスに属しています。 何処に属しているか確認する為に.classメソッドが使えます。 s = "文字列" s.class ⇒ String 実はStringクラスもObjectクラスに属しています。 >> s.class.superclass # superclass : 親クラスを調べる => Object Objectクラスも更に上のクラスに属しています。 >> s.class.superclass.superclass => BasicObject BasicObjectは更に上のクラスに属している? 答えはNoでした。nilは存在しないという意味です。 >> s.class.superclass.superclass.superclass => nil なんでこんな事をしているのかというと・・・機能を引き継ぐ為です。('ω')ノ Objectクラスの下には、String(文字列)・Integer(整数)・Array(配列)クラスなどがあります。 配列も、整数も、文字列も、.lengthメソッドが使えますよね。 3つそれぞれ追加していくのは大変ですよね。 なのでObjectに追加して下位クラスで利用出来るようにすれば手間が省けます。 この様に上位のクラスで定義されたメソッドを下位メソッドに引継ぐ事を『継承』と言います('ω')ノ #class <クラス名>で新しいクラスを定義できます。 >> class Word < String # < StringでStringクラスを継承出来ます('ω')ノ >> # 文字列が回文であればtrueを返す >> def palindrome? # defで新しいメソッドを定義できます。 >> self == self.reverse # selfは文字列自身を表します >> end >> end => :palindrome?Ruby 基礎
$ rails console #整数の足し算 >> 17 + 42 => 59 #文字列の結合 >> "foo" + "bar" # 文字列の結合 => "foobar" #変数の代入 >> first_name = "Michael" => "Michael" #文字列の式展開 これ便利('ω')ノ Railsでも使うよ。 >> "#{first_name} Hartl" => "Michael Hartl" #式展開('ω')ノ >> first_name = "Michael" => "Michael" >> last_name = "Hartl" => "Hartl" >> first_name + " " + last_name # 苗字と名前の間に空白を入れた結合 => "Michael Hartl" >> "#{first_name} #{last_name}" # 式展開を使って結合 (上と全く同じ) => "Michael Hartl" #文字列の出力 (puts) >> puts "foo" # 文字列を出力する foo => nil #戻り値はnilは「何にもない」 #文字列の出力 (print) >> print "foo" # 文字列の画面出力 (putsと同じだが改行しない) foo=> nil >> print "foo\n" # \nは改行。これでputsと同じ出力になる。 foo => nil #''シングルクォーテーションと""ダブルクォーテーション >> '#{first_name} #{last_name}' # ''は式展開できない。 => "/#{first_name} #{last_name}" >> "#{first_name} #{last_name}" # ""は式展開できる。 => "Michael Hartl" # empty?メソッド >> "foobar".empty? => false >> "".empty? => true #条件分岐 (if) ・.include?("文字列") ・.nil? メソッド >> if s.nil? >> "The variable is nil" >> elsif s.empty? >> "The string is empty" >> elsif s.include?("foo") >> "The string includes 'foo'" >> end => "The string includes 'foo'" # バン!バン! 強制的に論理値(True/False)で出力する >> !!nil #Rubyオブジェクトはnilだけfalse => false >> !!0 #その他のあらゆるRubyのオブジェクトはtrue => trueこれで半分程度の内容ですかね。結構ボリューム多いです。
配列やハッシュといった重要な内容がこの後に続くのですが・・・
全部書くと著作権的にどうなのかなと思うのでシンボルについて書いたら終わりッス('ω')ノシンボルと整数、文字列について
#これはハッシュというラベル付配列です。 user1 = { "name"=>"test_user", "email" => "test_user@example.com" } user2 = { "name"=>"test_user", "email" => "test_user@example.com" } user1 == user2 => false 同じ内容なのに falseになるのはなんで?('ω')ノ 実はobject_idというモノが違っているから、異なっているのを確かめてみてください。 user1.object_id user2.object_id このobject_idってデータの格納されている場所みたいなものです。 文字列でも試してください。実行する度にobject_idが代わるんです。 "name".object_id "name".object_id "name".object_id 次に数字です。数字はどうでしょうか? 数字は常に同じobject_idになるんです。 1.object_id 1.object_id 1.object_id 最後に・・・シンボルです。 シンボルも数字と同じくobject_idが変化しないんです。 :name #:+文字列をシンボルって言うのですが、object_idにラベル付けたモノって思ってください。 なんでこんな事をするかというと、文字列を使うよりも処理速度が速くなるからです。('ω')ノ なのでハッシュのラベル名は文字列よりもシンボルの方が好まれます。 ◎ user = { :name=> "test_user" , :email => "test_user@example.com" } △ user = { "name"=>"test_user", "email" => "test_user@example.com" } 更にもっと簡単に記述もできます。 user = { :name=> "test_user" , :email => "test_user@example.com" } user = { name: "test_user", email: "test_user@example.com" }カスタムヘルパー
自分でメソッドを定義する場合にヘルパーというファイルに記述します('ω')ノ
app/helpers/application_helper.rbmodule ApplicationHelper # ページごとの完全なタイトルを返します。 def full_title(page_title = '') base_title = "Ruby on Rails Tutorial Sample App" if page_title.empty? base_title else page_title + " | " + base_title end end end感想
第四章は非常に内容が濃くて面白いです。
自分で様々なメソッドを定義する為にはRubyの知識が必要になってきますね。
いろんなメソッドが存在するけど、ほんの僅かしか覚えていないので
Railsの学習が終わったら、Rubyもきちんと学習しないと駄目ですね・・・。
はぁー、先が長い長い( ^ω^)・・・。
- 投稿日:2020-10-28T12:32:31+09:00
【備忘録】Fizz_Buzz問題について(RubyonRailsの動き方)
本稿について
PFを作成後、改めてFizz_Buzz問題をRubyで入力していたところ、
少し理解が深まったので、備忘録として残します。Fizz_Buzz問題とは
プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3で割り切れる場合は「Fizz」(Bizz Buzzの場合は「Bizz」)、5で割り切れる場合は「Buzz」、両者で割り切れる場合(すなわち15で割り切れる場合)は「Fizz Buzz」(Bizz Buzzの場合は「Bizz Buzz」)を数の代わりに発言しなければならない。発言を間違えた者や、ためらった者は脱落となる。
Wikiより転記:https://ja.wikipedia.org/wiki/Fizz_Buzzこれをプログラムで書くと、条件分岐(if文等)と繰り返し(for文等)が必要になるため、初学者の練習問題となることが多い。
fizz_buzz.rbdef fizz_buzz(number) if number % 15 == 0 puts "fuzz_buzz" elsif number % 5 == 0 puts "buzz" elsif number % 3 == 0 puts "fuzz" else puts number.to_s end end puts "1以上の数値を入力してください" for i in 1..5 do print fizz_buzz(gets.to_i) endRubyonRailsで言うと
controllerで下記のような、プログラムをよくみる
users_controller.rbdef show @user = User.find(params[:id]) endfizz_buzz.rbで言うところのgets.to_iがviewファイルで行われ、controllerの処理が実行されている。
わかっている人にとっては、当たり前だろうが府に落ちたので
以上です
- 投稿日:2020-10-28T12:30:07+09:00
【Ruby on Rails】サクッとブラウザでページタイトルを表示
目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalinaベースとなるタイトルの編集
application_helper.rbmodule ApplicationHelper def full_title(page_title = '') base_title = "アプリ名" if page_title.empty? base_title else "#{ page_title } | #{ base_title }" end end endhead内のタイトルを編集
application.html.erb<head> <title><%= full_title(yield(:title)) %></title> </head>各ページのタイトルを追加
今回はaboutページがあると想定します。
追加場所は一番上でOKです。app/views/homes/about.html.erb<%= provide(:title, 'サイトについて')%>Qiita記事のようにカラムを使用してタイトルを表示する場合は
下記のように記述すればOKです。app/views/homes/about.html.erb<%= provide(:title, @genre.name)%>まとめ
これらを実施する事により、ユーザーが現在どの位置にいるかを把握することができ、
ユーザーの離脱率改善に繋がりますので、必須の搭載機能だと言えます。またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork
- 投稿日:2020-10-28T12:25:36+09:00
Railsで簡単な通知機能(フォローされた時のみ)
Railsでの簡単な通知機能です。(とりあえずフォローされた時のみ)
ルーティングの設定
config/routes.rbresources :notifications, only: [:index]コントローラの作成
$ rails g controller notificationsモデルの作成
$ rails g model Notification visitor_id:integer visited_id:integer$ rails db:migrateモデルとアソシエーションの設定
app/models/user.rbhas_many :active_notifications, class_name: "Notification", foreign_key: "visitor_id", dependent: :destroy has_many :passive_notifications, class_name: "Notification", foreign_key: "visited_id", dependent: :destroy def create_notification_follow!(current_user) temp = Notification.where(["visitor_id = ? and visited_id = ? ",current_user.id, id]) if temp.blank? notification = current_user.active_notifications.new(visited_id: id) notification.save if notification.valid? end endapp/models/notification.rbbelongs_to :visitor, class_name: 'User', foreign_key: 'visitor_id' belongs_to :visited, class_name: 'User', foreign_key: 'visited_id'コントローラの設定
app/controllers/relationships_controller.rbdef create @user = User.find(params[:user_id]) current_user.follow(params[:user_id]) @user.create_notification_follow!(current_user) #追記部分 redirect_to request.referer endapp/controllers/notifications_controller.rbdef index @notifications = current_user.passive_notifications.order(created_at: :DESC) endビュー(通知一覧)の設定
app/views/notifications/index.html<h1>おしらせ</h1> <% if @notifications.exists? %> <% @notifications.each do |notification| %> <table> <tr> <td> <%= attachment_image_tag notification.visitor, :image, size: "50x50" %> </td> <td> <%= link_to user_path(notification.visitor) do %> <%= notification.visitor.name %> <% end %> </td> <td> からフォローされました。 </td> <td> <%= " (#{time_ago_in_words(notification.created_at)}まえ)" %> </td> </tr> </table> <% end %> <% else %> <p>おしらせはありません</p> <% end %>
- 投稿日:2020-10-28T08:05:20+09:00
Ruby の Gem で ウエブフレームワーク を検索してみた
はじめに
気が向いたので、やってみた
検索結果
gem last Roda 3.37.0 - October 16, 2020 Ruby on Rails 6.0.3.4 - October 07, 2020 Scorched 1.0.1 - August 28, 2020 Cuba 3.9.3 - August 11, 2020 Sinatra 2.1.0 - September 04, 2020 Pakyow 1.0.6 - September 03, 2020 Rack::App 2.2.3 - June 15, 2020 Padrino 0.15.0 - May 15, 2020 Syro 3.2.0 - February 28, 2020 Hanami 2.0.0.alpha1 - January 30, 2019 Hobbit 0.6.1 - February 20, 2016 Camping 2.1.532 - March 21, 2013 Ramaze 2012.12.08 - December 08, 2012 Hyperstack - まとめ
- いろいろあります
参照したサイト
RubyGems.
Awesome Ruby : 素晴しい Ruby のライブラリ・ツール・フレームワーク・ソフトウェアの数々
- 投稿日:2020-10-28T02:24:31+09:00
to_sメソッドについて。
to_sメソッドの説明
数値が持つメソッドです。数値を文字列に変換してくれます。
ちなみに、 to_sのsの意味は「string(文字列)」です。
以下の例を見てください。【例】irb# 数値「20」にto_sメソッドをつけて実行 irb(main):001:0> 20.to_s => "20"to_sメソッドによって、文字列"20"が実行結果になっています。
それでは、文字列と数値を連結させて、
"i am 20 years old."を表示しましょう。irbで以下のコードを実行しましょう
では、実際にターミナルでto_sメソッドを試してみましょう。
ターミナル# to_sで数値を文字列に変換し、連結 irb(main):001:0> "i am " + 20.to_s + " years old." # 続けてこのように表示されれば成功 => i am 20 years old.「はじめから文字列"20"を用意すればよかったのでは?」と思うかも
しれません。しかし、足し算した結果を文字列として利用したい場合など、
数値を文字列に変換するto_sメソッドを利用する場面は多くあります。
この方法は必ず覚えておきましょう。反対に文字列を数値に変換するメソッドもあります。それがto_iメソッドです。これは文字列がもつメソッドです。
to_iメソッドについては、次回説明させていただきます。まとめ
to_sメソッドとは、数値を文字列に変換するメソッド。
以上。
- 投稿日:2020-10-28T01:17:38+09:00
RSpec Setup
RSpecのセットアップ
参考文献
Everyday Rails - RSpecによるRailsテスト入門
https://leanpub.com/everydayrailsrspec-jp環境 Mac
Ruby 2.4.9
Rails 5.1.1Rspec導入における忘備録である。
RSpecのインストール
GemFileを開き、テスト環境と開発環境で使用可能なように
下記のグループにRSpecを追記する。GemFile.group :development, :test do #追加 バージョン指定は各環境に応じて変更してください。 gem 'rspec-rails', '~> 3.6.0' end下記のコマンドを入力
ターミナル.bin/rails g rspec:installすると下記のフォルダが作成される。
ターミナル.Running via Spring preloader in process 53239 create .rspec create spec create spec/spec_helper.rb create spec/rails_helper.rbこれで準備完了。
お次に、テスト時にターミナルに流れるRSpecの出力を読みやすいドキュメント形式に変更
.rspecに下記を記載する。#デフォルトで記載されている。 --require spec_helper #こっちを追記 --format documentationrspec binstubの導入
binstubとはなんぞや?
アプリケーションの起動を早くすることが可能で、bundle exec ~からbin/~と呼び出しも楽になる便利屋さん。参考URL
https://qiita.com/tanaka51/items/bc22c1c364202d3cce4e開発環境に追記してbundle
GemFile.group :development do gem 'spring-commands-rspec' end続いてターミナルに下記コマンドを打ち込むと、
Railsアプリケーションディレクトリ直下にあるbinディレクトリ内にRSpecが新たに加わる。ターミナル.bundle exec spring binstub rspecここまで完了したら
ターミナル.bin/rspecでテストが走るか確認する。
rspecディレクトリ内のテストを一括で回してくれるので、最高に楽である。
そして、2回目の実行がめちゃくちゃ早い。VSCode民のためのテストプラグイン
これはテストコードを開いてcmd + shift + t でその画面のテストをVSCodeが実行してくれるという便利拡張機能!
かなりオススメ
rails g で一緒にRSpecファイルも作成してもらう
ジェネレーターでアプリケーションにコードを追加する際に一緒にRSpecのテストファイルも作ってもらう。
しかし、使用しないディレクトリ及びテストファイルまで作成されては困るので、同時に、使用しないものを作らない設定も行う。config/application.rb内に追記していく。
config/application.rbmodule Projects class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 5.1 # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. #ここから下を追記 config.generators do |g| #ジェネレート時にRSpecのテストファイルも作成 g.test_framework :rspec, #テストデータベースにレコードを作成するファイルの作成をスキップ fixtures: false, #ビュースペックを作成しないことを指定 view_specs: false, #ヘルパーファイル用のスペックを作成しないことを指定 helper_specs: false, #ルーディング用のスペックファイルの作成を省略 routing_specs: false end #ここまで end endもし手動で追加したいのであれば、
テストしたいファイルのディレクトリ名とファイル名を合わせて作成する
app/helpers/projects_helper.rb をテストするのであれば、spec/helpers/projects_helper_spec.rb を作成する。最後に、Railsがデフォルトで用意してあるテストディレクトリを削除しておきましょう!
ちなみに、RSpecのファイルのみ作成したい場合は下記のジェネレートコマンドを入力すれば、作成される。
下記の場合は、RSpecディレクトリに、modelディレクトリが作成されて、userのRSpecファイルが作成される。spec/models/user_spec.rb
ターミナル.bin/rails g rspec:model user #結果 create spec/models/user_spec.rb今回はここまでにします。
間違い、誤記、ご助言等ございましたらご教授くださると幸いです。
ありがとうございました。