- 投稿日:2019-07-09T23:46:55+09:00
今日の学習
やったこと
・atom のエディターをオートセーブに設定。
・メソッドについて
学んだこと
・atom のエディターをオートセーブに設定やり方
→atom →Preference→Packagesで「autosave」を検索、[Settings]でEnabledにチェックを入れる。
・メソッドについて
・メソッド
メソッドはユーザーが独自に定義するいことができる関数のこと。メソッドを定義することにより、共通した処理をひとまとめにし、メソッドを呼び戻すことで何度でも使うことができる。
Rubyのメソッドは始まりにdefを指定して、終わりをendを記述し、その中に実行する処理を記述する。
↓
def メソッド名
実行する処理
endメソッドの使い方
ex say と言うメソッドを定義する場合
↓
def say
puts "YOLO" #You Only Live Once(人生は一度きり)
endsay
実行結果→YOLO
またメソッドにあらかじめ引数を設定することができる。
ex goodbyeという引数付きのメソッドを定義する場合。
def goodbye(name)
puts "Goodbye #{name}"
endgoodbye("World!")
実行結果→Goodbye World!
文字列の中で、メソッドで渡した値を使用したい時、#{}で変数を囲む必要がある。
今回はnameが引数のため#{name}となる。メソッドの呼び出し
通常メソッドというのは全てクラスに定義されている。
→(あるクラスを継承した)オブジェクト.メソッド名(第1引数、第2引数、…)){ブロック}
例えば、rubyのなかの文字列オブジェクトのクラスはstringであるため、stringクラスのメソッドを使うことができる。1 name = "Samurai" #文字列オブジェクトnameを定義
2
3 "Samurai".class #クラスを確認→Stringクラスだった
4
5 p name #=> "Samurai" #中身が侍であることを確認
6
7 name.replace("Bushi") #Stringクラスからreplaceメソッドを呼び出す(文字列SamuraiをBushiに入れ替える)
8
9 p name #=> "Bushi" #ちゃんと入れ替わった
10この場合、継承したオブジェクトはnameでメソッドはreplaceである。
そしてreplaceの第一引数はBushiである。トップレベルにメソッドが定義されてた場合はオブジェクトの省略をしてメソッドを呼び出すことができる。
先ほどの
→def goodbye(name)
puts "Goodbye #{name}"
end
goodbye("World!")また、{ブロック}を渡す場合は例えば配列の場合だと
→a = [1,2,3]
a.each{|content| p content}実行結果
→[実行結果]
1 1
2 2
3 3{|content| p content}の部分がブロックを渡している部分。
補足、追加
変数の使い方https://www.sejuku.net/blog/12879
defを使ってメソッドを定義するhttps://www.sejuku.net/blog/19275
クラスメソッドの使いかたhttps://www.sejuku.net/blog/19208
- 投稿日:2019-07-09T22:57:11+09:00
MaterializecssのCarouselを使用して、不特定多数の@変数sをeachで表現する
概要
TECH::EXPERTのカリキュラムでオリジナルのミニアプリを作成する機会があり、
その一部のページでMaterializecssのCarouselを使用し、users_controller.rb
で定義した@usersをそれぞれ"carousel-item"で表現したので紹介します。MaterializecssのCarouselとは
画像をくるくると回せる機能です。
https://materializecss.com/carousel.html自分が作成したページ紹介
画像が自動で切り替わる方法は
こちらを参照していただけば幸甚です(ついでにイイね)
作成する前提
MaterializecssがCDNで読み込めている
編集するファイル
・コントローラーファイル
・ビューファイルコントローラーファイル
user_contoroller.rbdef show user=User.find(params[:id]) @users=User.where(training: user.training) end上の例では、表示しているuserページのuserのtrainingと同じtrainingを持っている人を
@usersで定義してます。ビューファイル
show.html.erb<div class="card"> <h6>この人と同じトレーニングが好きな人</h6> <div class="carousel #fafafa grey lighten-5" id="recommend_user" > <% users.each do |user| %> <a class="carousel-item" href= "/users/<%= user.id %>" data-id ="<%=user.id %>" > <%=user.nickname%> <img src=""> <%= image_tag image(user),class:'circle' %> </a> <%end%> </div> </div>eachメソッドで"carousel-item"ごと表現しています。
名前とプロフ画像を描画してます。最後に
この記事を書いた目的
・自分なりに工夫した点をアウトプットして、理解を深める。
・あわよくば有識者にフィードバックをもらいたい。
・私と同じ初学者からも奇譚のない意見をもらいたい。(自分だったらどうこうする的な)筆者について
TECH::EXPERTにて4月27日より52期夜間・休日コースでruby/railsを学習している未経験エンジニアです。
ご不備等ありましたら、ご指摘ください。ちなみに本記事が初投稿になります。
言わずもがなかもしれませんが、趣味はボディメイク・筋トレでございます。
余談ですが、120kg⇨66kgまで減量して大会出場した経験があり
ダイエットについての質問はなんでも答えられるかと思いますひとこと
最後までご覧いただきまして、ありがとうございました。
もし気に入っていただけたら、イイね・ストック・フォローご自由に!
- 投稿日:2019-07-09T21:58:02+09:00
[Ruby] DelegateClass を使って僕だけの Logger を実装する
例
標準出力に出力するための Logger オブジェクトを作りたい
require 'logger' logger = Logger.new(STDOUT) logger.formatter = Logger::Formatter.new logger.datetime_format = '%Y/%m/%d %H:%M:%S ' logger.info('BONFIRE LIT') logger.error('YOU DIED')I, [2019-07-09T21:40:12.663123 #18929] INFO -- : BONFIRE LIT E, [2019-07-09T21:40:13.036144 #18929] ERROR -- : YOU DIEDこのような形で毎回 logger オブジェクトを作るのは大変だから、クラス化しよう
require 'forwardable' require 'logger' class StdoutLogger extend Forwardable def_delegators :logger, :debug, :info, :warn, :error, :fatal private def logger @logger ||= Logger.new(STDOUT).tap do |logger| logger.formatter = Logger::Formatter.new logger.datetime_format = '%Y/%m/%d %H:%M:%S ' end end end logger = StdoutLogger.new logger.info('BONFIRE LIT') logger.error('YOU DIED')以前はこのように「Logger オブジェクトである
loggerを所有し、infoやerrorなどのメソッドをloggerに委譲する」というクラスを実装していました。しかし、この方法では委譲したいメソッドが増えた場合、例えば Logger#unknown も委譲したい場合などにdef_delegatorsに追記しなくてはいけませんそこで便利なのが Kernel#DelegateClass です。
require 'delegate' require 'logger' class StdoutLogger < DelegateClass(Logger) def initialize super(logger) end private def logger @logger ||= Logger.new(STDOUT).tap do |logger| logger.formatter = Logger::Formatter.new logger.datetime_format = '%Y/%m/%d %H:%M:%S ' end end end logger = StdoutLogger.new logger.info('BONFIRE LIT') logger.error('YOU DIED')
DelegateClass(Logger)を継承することで、Logger のインスタンスメソッドはすべてloggerに委譲されます。最後に
DelegateClassは非常に便利で、例えば Array のラッパークラスを定義したい場合にも使えます。これについては以前書いたという記事を参照してください。
Logger 関連でよろしければこちらの記事もご覧ください。
- 投稿日:2019-07-09T21:58:02+09:00
[Ruby] DelegateClass を使って僕だけの Logger を実装する (追記あり)
例
標準出力に出力するための Logger オブジェクトを作りたい
require 'logger' logger = Logger.new(STDOUT) logger.formatter = Logger::Formatter.new logger.datetime_format = '%Y/%m/%d %H:%M:%S ' logger.info('BONFIRE LIT') logger.error('YOU DIED')I, [2019-07-09T21:40:12.663123 #18929] INFO -- : BONFIRE LIT E, [2019-07-09T21:40:13.036144 #18929] ERROR -- : YOU DIEDこのような形で毎回 logger オブジェクトを作るのは大変だから、クラス化しよう
require 'forwardable' require 'logger' class StdoutLogger extend Forwardable def_delegators :logger, :debug, :info, :warn, :error, :fatal private def logger @logger ||= Logger.new(STDOUT).tap do |logger| logger.formatter = Logger::Formatter.new logger.datetime_format = '%Y/%m/%d %H:%M:%S ' end end end logger = StdoutLogger.new logger.info('BONFIRE LIT') logger.error('YOU DIED')以前はこのように「Logger オブジェクトである
loggerを所有し、infoやerrorなどのメソッドをloggerに委譲する」というクラスを実装していました。しかし、この方法では委譲したいメソッドが増えた場合、例えば Logger#unknown も委譲したい場合などにdef_delegatorsに追記しなくてはいけませんそこで便利なのが Kernel#DelegateClass です。
require 'delegate' require 'logger' class StdoutLogger < DelegateClass(Logger) def initialize super(logger) end private def logger @logger ||= Logger.new(STDOUT).tap do |logger| logger.formatter = Logger::Formatter.new logger.datetime_format = '%Y/%m/%d %H:%M:%S ' end end end logger = StdoutLogger.new logger.info('BONFIRE LIT') logger.error('YOU DIED')
DelegateClass(Logger)を継承することで、Logger のインスタンスメソッドはすべてloggerに委譲されます。ちなみに
Loggerクラスを継承する方法では最後に
DelegateClassは非常に便利で、例えば Array のラッパークラスを定義したい場合にも使えます。これについては以前書いたという記事を参照してください。
Logger 関連でよろしければこちらの記事もご覧ください。
追記: 通常の継承の方がいいような……
この場合 Logger クラスを継承する方法でもいいような……。
require 'logger' class StdoutLogger < Logger def initialize super(STDOUT, formatter: Formatter.new, datetime_format: '%Y/%m/%d %H:%M:%S ') end end logger = StdoutLogger.new logger.info('BONFIRE LIT') logger.error('YOU DIED')違いのひとつとして、Logger クラスのサブクラスかどうかが異なる。
# DelegateClass(Logger) を継承する場合 logger.is_a?(Logger) #=> false # Logger を継承する場合 logger.is_a?(Logger) #=> trueこの場合、むしろ Logger オブジェクトであると見なしたほうが適切かもしれない。
- 投稿日:2019-07-09T21:37:24+09:00
あなたはRailsチュートリアルで一体なにを学んだというのか【3章】
注意:プログラミング歴29日の初心者が書いています
注意:間違っていたら優しく教えてください(喜びます)
「Ruby on Rails チュートリアル実例を使ってRailsを学ぼう」
https://railstutorial.jp/素晴らしいチュートリアルに感謝します。
3.2 静的ページ
トピックブランチを切る
$ git checkout -b static-pages: 変更を行う時には、masterではなく、ブランチを作成して作業します。(ブランチを作成することを「切る」と言います)
作成したブランチ上で、こまめにコミットしながら作業を進めることができます。でも、本流のmasterにはなんの影響も及ぼしませんので思う存分コミットできます。
また、複数人がそれぞれブランチを用意して同時進行で作業することも可能です。
3.2.1 静的なページの生成
コントローラの生成(ルーティングの追加とviewも同時生成)
$ generate controller StaticPages home help: StaticPagesコントローラを生成する(そのなかには、homeとhelpというページへのアクションも含む)同時に「routes.rb」ファイルには、StaticPagesコントローラ内のhomeアクションとhelpアクションで使うルーティングが自動で書き込まれます。
これによって、今後rootURLの末尾に、
/static_pages/homeや/static_pages/helpと付け加えることで、StaticPagesコントローラ内のhomeアクションとhelpアクションにアクセスが可能です。class StaticPagesController < ApplicationController def home end def help end endStaticPagesコントローラ内では、homeアクションとhelpアクションが自動で定義されています。そして、それらによって対応するviewが呼び出されます。
では、viewディレクトリを見てみると、こちらにも自動で
home.html.erbとhelp.html.erbが生成されています。これがブラウザに表示されるHTMLの一部になっています。コントローラの中のクラスとメソッドについて
class StaticPagesController < ApplicationController def home end def help end endStaticPagesコントローラ内は以下の構成になっています。
StaticPagesControllerクラスの定義
クラスメソッド(アクション)の定義:
def~end部分Rubyにおいて、メソッドとは関数のことです。
ここでは、「home」「help」という名前のついた関数が定義されていますが、中身は空っぽです。通常、このように中身の空っぽのメソッドは何もしません。
では、なぜこれらのメソッドは対応するURLリクエストに反応して適切なviewを返してくれるのでしょうか?
それは、StaticPagesControllerクラスがApplicationコントローラクラスを継承しているからです。
そして、ApplocationコントローラクラスはActionController::Baseクラスを継承しています。
ActionController::Baseクラスが、rails特有のコントローラとしての動きを定義しています。今回あたらしく作成したStaticPagesControllerクラスと、その中の空っぽのメソッドが機能しているのは、ActionController::Baseクラスのコントローラ機能を継承しているからです。
3.3 テストから始める
テスト駆動開発(TDD)については、以下の動画をみると一通りやるべきこととその動機がわかります。
「50分でわかるテスト駆動開発」
https://channel9.msdn.com/Events/de-code/2017/DO03test "should get home" do get static_pages_home_url assert_response :success end言葉で表すと
「Homeページのテスト。
GETリクエストをhomeアクションに対して発行 (=送信) せよ。
そうすれば、リクエストに対するレスポンスは[成功]になるはず」
となります。3.4 少しだけ動的なページ
テストから先に書いて、テストが通る実装を書いていく
assert_select "title", "Home | Ruby on Rails Tutorial Sample App"assert_selectメソッドは、特定のHTMLタグが存在するかどうかをテストします。
assert_select "title", "タイトル" # titleタグの文字列が、「タイトル」と一致すれば成功。テストに合わせて、それぞれのviewファイルを修正していきます。
1ページ修正するごとにテストを行うと、ちゃんと「failures」が減っていくことがわかります。テストコードをリファクタリングする
"Ruby on Rails Tutorial Sample App" というタイトルの一部がなんども繰り返されています。
同じことをなんども繰り返すのは美しくありませんので、変数に格納してから使う形にリファクタリングします。以下は
test/controllers/static_pages_controller_test.rbの一部です。def setup @base_title = "Ruby on Rails Tutorial Sample App" endここではまず、"Ruby on Rails Tutorial Sample App"を
@base_titleというインスタンス変数に格納しています。
「インスタンス変数」とは、同じクラス内で使える変数のことで、頭に@がついています。
ここではStaticPagesControllerTestクラスで使用可能なインスタンス変数として、@base_titleを定義しました。assert_select "title", "Home | Ruby on Rails Tutorial Sample App"つづいて上記の"Ruby on Rails Tutorial Sample App"を
@base_titleという変数に置き換えていきます。assert_select "title", "Home | #{@base_title}"
${@base_title}という形で、変数が${}の中に入っています。
これは、"文字列"の中で変数を使う時のルールです。
これを「文字列の式展開」といいます。もしも変数
@base_titleがもし${}の中に入っていなかったら、"@base_title"という、ただの文字列として処理されてしまいます。
"Ruby on Rails Tutorial Sample App"として@base_titleを使う場合は、${}の中に入れてあげる必要があるということです。変更が終わったら、コンソールからテストを走らせて、エラーがないことをチェックします。
3.4.3 レイアウトと埋め込みRuby (Refactor)
Rubyの文法をHTML内で使うときには、
<% %>でRubyコードを囲みます。provide(:title, "Home")ここでは、
:titleというシンボルに、文字列"Home"を紐づけて、擬似的なハッシュのようなものを作っています。
ただしprovideメソッドで宣言したこのシンボルと文字列の擬似ハッシュは、このHomeページ内でしか使うことはできません。<title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>その後、
yield(:title)で文字列"Home"を呼び出しています。
Rubyの文法をHTML内で使い、かつ結果を出力するときには、<%= %>でRubyコードを囲みます。今回は呼び出した文字列をHTML内に出力したいので、
<%= %>でRubyコードを囲んでいます。レイアウトファイルのリファクタリング
レイアウトファイルは、全てのページで共通する
や部分を担うviewです。共通部分をレイアウトファイルに統一することによって、個別のviewファイルの記述を減らし、シンプルに保つことができます。
- 投稿日:2019-07-09T21:35:18+09:00
f.selectで生成されるoptionタグを改変する
やりたいこと
"f.select"で生成されるセレクトボックスの中身(optionタグ)をいじりたい
初期値を設定したい概要
= f.select :name, options_for_select(セレクトボックスで表示したい要素配列.map{|c|[セレクトボックスで表示される値, value属性値にセットしたい値, {追加属性記述}]}, 初期値のvalueを選択), {}, {class: 'hoge', id: 'hogehoge'}value属性値にセットしたい値の記述をなくすと
"value = セレクトボックスで表示される値"
になります具体例
#セレクトボックスの選択肢にしたい要素配列 @sample_array_1 = ['aaa', 'bbb', 'ccc'] @sample_array_2 = [{id: 1, name: "aaa"}, {id: 2, name: "bbb"}, {id: 3, name: "ccc"}] #初期値要素(データベースから読み取ったと仮定) @selected_sample_1 = 'bbb' @selected_sample_2 = {id: 2, name: "bbb"} #基本形1 = f.select :sample, @sample_array_1, {}, {class: 'hoge', id: 'hogehoge'} #基本形2 = f.select :sample, options_for_select(@sample_array_2.map{|c|[c[:name], c[:id]]}), {}, {class: 'hoge', id: 'hogehoge'} #属性追加1 = f.select :sample, options_for_select(@sample_array_1.map{|c|[c, {'data-sample'=>c}]}), {}, {class: 'hoge', id: 'hogehoge'} #属性追加2 = f.select :sample, options_for_select(@sample_array.map{|c|[c[:name], c[:id], {'data-sample'=>c[:id]}]}), {}, {class: 'hoge', id: 'hogehoge'} #初期値設定1 = f.select :sample, options_for_select(@sample_array_1.map{|c|[c, {'data-sample'=>c}]}, @selected_sample_1), {}, {class: 'hoge', id: 'hogehoge'} #初期値設定2 = f.select :sample, options_for_select(@sample_array.map{|c|[c[:name], c[:id], {'data-sample'=>c[:id]}]}, @selected_sample_2.id), {}, {class: 'hoge', id: 'hogehoge'}基本形1
= f.select :sample, @sample_array_1, {}, {class: 'hoge', id: 'hogehoge'}#基本形1 <select class="hoge" id="hogehoge" name="sample"> <option value="aaa">aaa</option> <option value="bbb">bbb</option> <option value="ccc">ccc</option> </select>基本形2
= f.select :sample, options_for_select(@sample_array_2.map{|c|[c[:name], c[:id]]}), {}, {class: 'hoge', id: 'hogehoge'}#基本形2 <select class="hoge" id="hogehoge" name="sample"> <option value="1">aaa</option> <option value="2">bbb</option> <option value="3">ccc</option> </select>属性追加1
= f.select :sample, options_for_select(@sample_array_1.map{|c|[c, {'data-sample'=>c}]}), {}, {class: 'hoge', id: 'hogehoge'}#属性追加1 <select class="hoge" id="hogehoge" name="sample"> <option data-sample="aaa" value="aaa">aaa</option> <option data-sample="bbb" value="bbb">bbb</option> <option data-sample="ccc" value="ccc">ccc</option> </select>属性追加2
= f.select :sample, options_for_select(@sample_array.map{|c|[c[:name], c[:id], {'data-sample'=>c[:id]}]}), {}, {class: 'hoge', id: 'hogehoge'}#属性追加2 <select class="hoge" id="hogehoge" name="sample"> <option data-sample="1" value="1">aaa</option> <option data-sample="1" value="1">bbb</option> <option data-sample="1" value="1">ccc</option> </select>初期値設定1
= f.select :sample, options_for_select(@sample_array_1.map{|c|[c, {'data-sample'=>c}]}, @selected_sample_1), {}, {class: 'hoge', id: 'hogehoge'}#初期値設定1 <select class="hoge" id="hogehoge" name="sample"> <option data-sample="aaa" value="aaa">aaa</option> <option selected="selected" data-sample="bbb" value="bbb">bbb</option> <option data-sample="ccc" value="ccc">ccc</option> </select>初期値設定2
= f.select :sample, options_for_select(@sample_array.map{|c|[c[:name], c[:id], {'data-sample'=>c[:id]}]}, @selected_sample_2.id), {}, {class: 'hoge', id: 'hogehoge'}#初期値設定2 <select class="hoge" id="hogehoge" name="sample"> <option data-sample="1" value="1">aaa</option> <option selected="selected" data-sample="1" value="1">bbb</option> <option data-sample="1" value="1">ccc</option> </select>参考
https://stackoverflow.com/questions/18100834/how-to-make-the-f-select-rails-selected
https://stackoverflow.com/questions/5052889/ruby-on-rails-f-select-options-with-custom-attributes
- 投稿日:2019-07-09T19:51:01+09:00
Railsにおける新規アプリ作成手順まとめ
はじめに
この記事のRailsのバージョンは5.2.2.1です。
自分の備忘録としてメモします。今回は「memo-app」というアプリを作成する想定で書きます。
具体的な手順
新規アプリ作成コマンド
terminal$ rails new アプリケーション名 # アプリケーションを新規作成 $ rails new アプリケーション名 -オプション名 # オプションを付けてアプリケーションを作成この新規ファイル全体の事を
Railsアプリという。新規アプリ作成コマンドの具体例
terminal$ cd ~/projects # projectsディレクトリに移動 $ rails _5.2.2.1_ new memo-app -d mysql # 「memoapp」を「mysql」オプションで作成。バージョンを5.2.2.1で作成。 $ cd memo-app # 「memo-app」ディレクトリに移動 $ pwd # 現在のディレクトリのパスを表示続いてデータベースの作成を行う。
データベース作成コマンド
terminal$ rake db:create #database.ymlというファイルに基づいて作成される続いてルーティングの設定を行います(ルーティングに関するファイルはrails newコマンドですでに作成されている)
ルーティング設定の具体例
routes.rbRails.application.routes.draw do get 'memo' => 'memos#index' end続いてコントローラーの作成を行います。
コントローラー作成コマンド
terminal$ rails g controller コントローラ名 # コントローラを作成コントローラー作成コマンドの具体例
terminal$ rails g controller memos # memosコントローラを作成コントローラーファイル設定
memos_controller.rbclass MemosController < ApplicationController def index end end #indexアクションを定義後はビューファイルの作成を行います。
今回はindex.html.erbというファイル名で作成します。
この際拡張子がerbになっている事に注意。(rubyを埋め込めるHTMLだと思っておけばOK)モデルの作成
terminal$ rails g model memo # Memoモデルを作成→モデルクラス名(全て小文字)この後にマイグレーションファイルで作成するカラムの設定などを行う。
マイグレーションファイルの作成
terminal$ rake db:migrate # マイグレーションファイルの実行DB上にmemosテーブルが作成される。
あとはrails sコマンドでサーバーを立ち上げればアプリとしての最低限のモノが。
各人カスタマイズして良いアプリを創っていきましょう。
- 投稿日:2019-07-09T17:08:27+09:00
RubyMine / Docker for Windows: docker-compose上で作ったrbenvのRuby環境をうまくロードできないトラブル 2019-07版
問題
- Windows 10 Pro
- RubyMine 2019.1
- docker-compose (Docker for Windows)
にて、Dockerコンテナ上でrbenvを使って作ったRuby環境を、RubyMineがうまくロードしてくれない。
解決方法を簡潔に
RubyMine 2019.2以降をインストールする。
ただし現状(2019-07-09)では Early Access Program (EAP) の段階なので、EAPのRubyMineを入れる。
※ 正式に2019.2以降がリリースされたときは、そちらをインストールしてください!(要ライセンス購入 or 試用)
前提
- ホスト
- Windows 10 Pro 10.0.18362
- Docker for Windows Community 2.0.0.3
- docker-composeを使用
- RubyMine
2019.12019.2
- これをバージョンアップする
- コンテナ
- Dockerイメージ:
centos:7
- docker-compose経由でDockerイメージを作成
Dockerfile
FROM centos:7 ENV APP_PATH /app WORKDIR ${APP_PATH} ENV ruby_ver="2.6.3" ENV RBENV_ROOT="/usr/local/rbenv" ENV RBENV_SH="/etc/profile.d/rbenv.sh" ENV CONFIGURE_OPTS="--disable-install-doc" ENV PATH="${RBENV_ROOT}/bin:${PATH}" # 日本語表示を正しくする (lessとRuby向け) ENV LESSCHARSET="utf-8" ENV LANG="en_US.UTF-8" # yum (EPEL): ビルドに必要なライブラリをインストール RUN set -x && \ yum -y update && \ yum -y install epel-release && \ yum -y install \ autoconf \ bzip2 \ curl \ gcc-c++ \ git \ glibc-headers \ libyaml-devel \ make \ openssl-devel \ readline \ readline-devel \ sqlite-devel \ zlib \ zlib-devel \ && \ yum -y install less which && \ yum clean all # Ruby (rbenv) のインストール RUN set -x && \ git clone https://github.com/sstephenson/rbenv.git /usr/local/rbenv && \ git clone https://github.com/sstephenson/ruby-build.git /usr/local/rbenv/plugins/ruby-build && \ echo 'eval "$(rbenv init --no-rehash -)"' > ${RBENV_SH} && \ source ${RBENV_SH} && \ rbenv install ${ruby_ver} && \ rbenv global ${ruby_ver} # Ruby: Bundlerで必要なGemをインストール COPY Gemfile ${APP_PATH} COPY Gemfile.lock ${APP_PATH} RUN set -x && \ source /etc/profile.d/rbenv.sh && \ rbenv exec gem install bundler && \ bundle install # その他、Rubyと関係ないインストールをここに書いている VOLUME [ ${APP_PATH} ]やったこと
- Early Access Program (EAP) からRubyMine 2019.2をダウンロードしインストールする
- Dockerfile中で
whichコマンドをインストールする:
yum -y install which- RubyMineがRubyのパスを検索するときにwhichを使う?
- RubyMineでDockerを設定する
- ポップアップが出るので、指示に従えばOK
- RubyMineのSettings
- Languages & Frameworks -> Ruby SDK and Gems
- 「+」→「New Remote...」をクリックする→ダイアログが表示される
- Configure Remote Ruby Interpreter ダイアログ
- 「Docker Compose」を選択
- Server: 既に設定したDockerの項目を選ぶ
- Service: docker-compose.ymlに書いたサービス名
- Ruby or version manager path (次に説明)
Ruby or version manager path
この項目は重要です。
動いた例
/usr/local/rbenv/bin/rbenv /usr/local/rbenv/versions/2.6.3/bin/ruby
- フルパス
2.6.3は実際にインストールしたRubyのバージョン番号- ユーザのホームディレクトリにインストールした場合は
/home/foo/.rbenv/versions/2.6.3/bin/rubyになるはずです。(試してませんが)うまく動かなかった例
ruby rbenv /usr/local/rbenv/bin/rbenv /usr/local/rbenv/shims/ruby参考
- RubyMineでremoteのrbenvで使っているgemを読みこませる - Qiita
- シンボリックリンクを使ったハックもあるようです(試してません)
これでOKをクリックして、Gemの一覧が出てくれば成功です!
以上です。
- 投稿日:2019-07-09T16:08:53+09:00
【備忘録】DockerでRuby 2.6.3, Rails 5.2.3, MySQL 8.0.16の環境を構築し,Herokuにデプロイするまで
Herokuにデプロイするまでにかなり時間がかかってしまったので,備忘録として。初心者なので,ミスや無駄があればコメントいただけるとありがたいです。
開発環境
- macOS Mojave 10.14.5
公式ドキュメント
参考
手順
1. インストール・新規登録
- 以下は,Homebrew, git, Docker desktopなどのインストール, GitHubの新規登録, Herokuの新規登録・クレジットカード登録などの初期作業を行っている前提とします
2. 作業ディレクトリ・Dockerファイルの作成
適当に作業ディレクトリを作成
ターミナルでの作業は必ずこのディレクトリ内で行うことファイル「Dockerfile」「docker-compose.yml」「Gemfile」「Gemfile.lock」を作成し,テキストエディタなどで以下を入力
(作業が面倒なら下記の【補足】を参照)DockerfileFROM ruby:2.6.3 ENV LANG C.UTF-8 RUN apt-get update -qq && \ apt-get install -y build-essential libpq-dev nodejs && \ rm -rf /var/lib/apt/lists/* RUN gem install bundler WORKDIR /tmp COPY Gemfile Gemfile COPY Gemfile.lock Gemfile.lock RUN bundle install ENV APP_HOME /my_app RUN mkdir -p $APP_HOME WORKDIR $APP_HOME COPY . $APP_HOMEdocker-compose.ymlversion: '3.2' services: db: image: mysql:8.0.16 command: mysqld --default-authentication-plugin=mysql_native_password volumes: - ./db/mysql_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: root ports: - "3306:3306" web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/my_app ports: - "3000:3000" links: - db tty: true stdin_open: trueGemfilesource 'https://rubygems.org' gem 'rails'Gemfile.lock※空ファイルでOK【補足】
上記ファイル作成作業が面倒なら,次のシェルスクリプトを作成して,ターミナルで実行してもよい。(コマンドはbash docker1.sh)docker1.sh#!/bin/bash # make Dockerfile cat <<'EOF' > Dockerfile FROM ruby:2.6.3 ENV LANG C.UTF-8 RUN apt-get update -qq && \ apt-get install -y build-essential libpq-dev nodejs && \ rm -rf /var/lib/apt/lists/* RUN gem install bundler WORKDIR /tmp COPY Gemfile Gemfile COPY Gemfile.lock Gemfile.lock RUN bundle install ENV APP_HOME /my_app RUN mkdir -p $APP_HOME WORKDIR $APP_HOME COPY . $APP_HOME EOF # make docker-compose.yml cat <<'EOF' > docker-compose.yml version: '3.2' services: db: image: mysql:8.0.16 command: mysqld --default-authentication-plugin=mysql_native_password volumes: - ./db/mysql_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: root ports: - "3306:3306" web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/my_app ports: - "3000:3000" links: - db tty: true stdin_open: true EOF # make Gemfile cat <<'EOF' > Gemfile source 'https://rubygems.org' gem 'rails' EOF # make Gemfile.lock touch Gemfile.lock3. Dockerイメージの作成
ターミナルで実行docker pull ruby:2.6.3 docker pull mysql:8.0.16 docker-compose run web rails new . --force --database=mysql --skip-bundle docker-compose build※「$」を付けるとコピペの邪魔になるので,以下も省きます
4. 「database.yml」を書き換える
config/database.ymldefault: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV.fetch("MYSQL_USERNAME", "root") %> password: <%= ENV.fetch("MYSQL_PASSWORD", "root") %> host: <%= ENV.fetch("MYSQL_HOST", "db") %> development: <<: *default database: my_app_development test: <<: *default database: my_app_test production: <<: *default database: my_app_production5. Dockerコンテナの作成・開始
ターミナルで実行docker-compose up6. データベースの作成
- 「Command + N」などで新しいターミナルを開き,作業ディレクトリまで移動
ターミナルで実行docker-compose exec web rails db:create
- この作業で「NoDatabaseError」が解消され,ブラウザから
http://localhost:3000にアクセスすると,「Yay! You’re on Rails!」が見られる。7. gitの準備
ターミナルで実行git init git add . git commit -m ”first commit”8. Herokuの準備
- ブラウザからHerokuにログインしておく
ターミナルで実行heroku login
- 適当なキーを押して,ログインボタンを押す
ターミナルで実行heroku create <アプリ名>
補足
- この作業で「Heroku」にアプリが作成されると同時に,「heroku」というgitのリモートリポジトリが作成される。
- <アプリ名>は自由。<>をターミナルに入力しないこと。
- すでに使用されているアプリ名は使用できない。
- アプリ名に「アルファベット大文字」は使えない。
- アプリ名を入力しなくてもよい(その場合はランダムに決定される)
データベースの設定をMySQLに変更する
ターミナルで実行heroku addons:add cleardb heroku config | grep CLEARDB_DATABASE_URL
- 表示された
mysql://〜〜〜の部分を取り出し,「mysql」を「mysql2」に変更- 次の
DATABASE_URL=の後にmysql2://〜〜〜を貼り付けたものをターミナルで実行ターミナルで実行heroku config:set DATABASE_URL=【補足】
ブラウザからアプリを選択し,「Setting」の「Reveal Config Vars」のページから編集してもよい。
「CLEARDB_DATABASE_URL」の
「CLEARDB_DATABASE_URL」を「DATABASE_URL」
「mysql」を「mysql2」に変更したものを追加すればよい。9. Herokuにデプロイ
ターミナルで実行git push heroku master heroku run rake db:migrate heroku openここまでで最低限度の作業は終了です。お疲れ様でした。
10. おまけ
- 終了するときは,ブラウザを閉じるだけでなく,HerokuのログアウトとDockerコンテナの停止をしておくこと
ターミナルで実行heroku logout docker-compose down
- コマンドの変更点
dockerを使用しないときのコマンドの例rails console rails g controller home top rails g model Post content:text rake db:migratedocker-composeコマンドの例docker-compose exec web rails console docker-compose exec web rails g controller home top docker-compose exec web rails g model Post content:text docker-compose exec web rake db:migrate
- 投稿日:2019-07-09T15:12:16+09:00
Rubyでmysqlのデータベースに接続する方法
Rubyだけでmysqlに接続する
今までRailsの力に頼ってきたのでrubyだけでmysqlに実行する方法を知らなかった
まずシステムにgemを入れる
gem install mysql2require 'mysql2' //requireする client = Mysql2::Client.new(host: "******", username: "******", password: '******', database: '******') result = client.query("select call_duration from talk_histories") //SQLここに書く result.each do |r| puts r["call_duration"] end
- 投稿日:2019-07-09T14:26:26+09:00
【Ruby】配列に入ったテーブルのデータを、特定のカラムを指定して並び替える
やりたいこと
通常テーブル内のデータの並び替えをする際は
モデル名.order('カラム名 desc')等で簡単に実行できます。
しかし今回はテーブル内全体のデータを対象とせずに、あらかじめ特定の条件に合ったレコードのみ配列に入れてあることを前提とします。
例えば以下のような感じ。users = [ #<User:0x000056357bd5c9b8> id: 2 name: "たろう", age: 16, copuntry: "Japan", #<User:0x000056357bd5c710> id: 6 name: "はなこ", age: 17, copuntry: "US", ・ ・ ・ ]この配列に対して並び替えを行いたいが、orderメソッドはそもそもモデルを対象にしか使用できません。
今回は配列にデータを入れてしまっているので、配列のデータの並び替え、しかも特定のカラムの値を対象に並び替えたいです。試行錯誤の履歴(必要ない方は飛ばしてください)
配列の並び替えだからsort_byメソッドだろうと予測はつきました。
https://ref.xaio.jp/ruby/classes/array/sort_by_bang●sort_byメソッドの使い方
こちらのRubyリファレンスをそのまま抜粋すると、使用方法は以下のような感じ。
test.rbanimals = ["mouse", "cat", "hippopotamus", "giraffe"] p animals.sort_by {|anim| anim.size } #出力結果 ==> ["cat", "mouse", "giraffe", "hippopotamus"]配列animalsの要素を、字数順に並べています。
この配列の場合は、配列の要素が単純なので問題はないんですが、
今回は配列の要素(1つのレコード)のさらに中の、カラムの値を指定して並び替える必要があるので、少し躓いてしまいました。●そもそも配列に保存されたデータ形式はどうなっているのか
そもそも配列にしたデータは、カラムを指定して特定の要素を呼び出せるのかが不安でした。
配列にしちゃってる時点で、nameやage等のカラム名をカラムとして認識してくれるのかわかりませんでした。しかし、改めてよく配列を見てみると
#<User:0x000056357bd5c9b8>とある。。
これは、"ちゃんとテーブルのデータとして一つ一つ保存している"に違いない!ということで
試しにコンソールで以下を実施してみました。users[0][:name] # 配列usersの1番目のデータを取得し、さらにそのnameカラムを指定してみる # 出力結果==> "たろう"ちゃんと拾えました!
データを配列に入れた際、ただの文字列として保存されるのではなく、テーブルのデータとして認識して保存されてるんですね。
多分超基本なんでしょうが、私は今回でやっと認識できました。。
基本すぎてすみません。。配列に関しての理解がまだまだでした。結果
以上のように色々と試行錯誤した結果、とてもシンプルに実行することができました!
例えばこの記事の一番上の配列usersに対して、ageカラムの値で並び替えしたい場合は、test.rbusers.sort_by(&:age)これだけです!
こうすると、ageの値が小さい順にデータを並び替えることができます。
sort_byメソッドの引数にageを指定するだけでした。
簡単すぎます。
- 投稿日:2019-07-09T12:50:34+09:00
あなたはRailsチュートリアルで一体なにを学んだというのか【2章】
注意:プログラミング歴29日の初心者が書いています
注意:間違っていたら優しく教えてください(喜びます)
「Ruby on Rails チュートリアル実例を使ってRailsを学ぼう」
https://railstutorial.jp/素晴らしいチュートリアルに感謝します。
2.1 アプリケーションの計画
アプリケーションを作成してbitbucketにpush
rails new: 新しいアプリケーションの作成
bitbucketで新しいリポジトリを作成(1章とは別のアプリを一からつくるから別のリポジトリ)
git remote add origin git@bitbucket.org:<username>/toy_app.git:新たに作成したファイル群をbitbucketのgit対象に指定
git push -u origin --all: bitbucketにプッシュ(アップロード)herokuにログインできないとき
ターミナルでheroku CLIにログイン
$ heroku login --interactiveパスワード入力それでも
heroku: command not foundとエラーがでるときは、
source <(curl -sL https://cdn.learnenough.com/heroku_install)でIDEにherokuをインストールしなおし。2.1.1 ユーザーのモデル設計
今、ツイッターみたいなアプリを作ろうとしています。
そのためのデータベースを作っていきます。ユーザーのモデル設計とは、その名の通り投稿を行うユーザーのデータベースです。
一人一人のユーザーは、
ID
name
の情報を持っています。
2.1.2 マイクロポストのモデル設計
マイクロポストは、ツイッターでいうところのツイートです。
1つ1つのマイクロポストは、
ID
Content (投稿内容)
user_id (誰が投稿したポストかわかるように)
の情報を持っています。
2.2 Usersリソース
データの集まりで、さらにWebで扱うことができる状態になっているのが、リソースです。
例えば、さっきのUsersモデル(ユーザーのデータベース)はそのままではただのデータの集まりですが、webサービスにおいては、新規追加したり、情報を編集したりするわけです。
「webから情報を扱う」というのは、HTTPで「新規登録しろ」とか「このユーザーのデータは削除だ!」とかリクエストできるということです。
そうゆうことができる状態のデータの集まりが、リソースです。
Railsのscaffold
Railsのscaffoldが、リソースを作る作業を全部やってくれます。
今回はそれに頼りましょう。2.2.1 ユーザーページを探検する
URLの末尾に
/usesをつけることで、user一覧ページにアクセスすることができます。
そのほかにも/newや/editなど、色々なことができるようになっています。
これは、「scaffold」コマンドが全て自動で設定してくれたからです。2.2.2 MVCの挙動
ルーティングってなんですか
ルーティングはURLとアクション(実行する内容)を紐づけている部分です。
Rails.application.routes.draw do resources :users root 'application#hello' end
root 'application#hello'は、『ルート(トップページ)は、appricationコントローラのhelloメソッドを使って表示してね』と言っています。さらに注意深く
routes.rbファイルの中を見ると、resources :usersというのが新たに追加されています。
これは「resourcesメソッド」です。まず、『「users」というURLに対しては、「usersコントローラを参照してね」』ということを言っています。
また、railsの特徴として、リソースに対するアクションはすでに7つ定義されています。
アクション名 役割 index リソースの一覧を表示させる show リソースの詳細を表示させる new 投稿フォームを表示させる create リソースを追加させる edit 更新フォームを表示させる update リソースを更新させる destroy リソースを削除する resourcesメソッドは、これら7つのアクションを自動的にUsersリソースに割り当てます。
データベースの操作内容まで、全てRailsが作ってくれているのです。
このように、最初から7つのアクションが定義してあって、それぞれのアクションの名前や、URLの末尾に付け足す内容までがルールとして決めてあります。
あなただけでなく、みんなが同じルールに則って開発すると、誰が見てもわかりやすくて管理しやすくなります。
ちなみに、今回使っているルールは「REST」と呼ばれています。詳しくはググるといっぱい出てきます。2.3.2 マイクロポストをマイクロにする
バリデーションとは
データベースにデータを保存する前に、そのデータが本当に保存していいのかどうか検証する仕組みをバリデーションといいます。
class Micropost < ApplicationRecord validates :content, length: { maximum: 140 } end
app/models/micropost.rb内のコードです。
ここでは、
- マイクロポストモデルの「content」の「length」がマックス140文字まで
というバリデーションを設けています。
2.3.3 ユーザーはたくさんマイクロポストを持っている
has_meny / belongs_toとは
has_menyは、モデルとモデルを関連づけるために使います。
今回のチュートリアルの場合、「Usersモデル」と「Micropostsモデル」を関連づけるために使います。class User < ApplicationRecord has_many :microposts endUserモデル(app/models/user.rb)内に「has_many :microposts」と記述することで、モデル同士が関連します。
ただし、マイクロポストがユーザーを持っているわけではないことに注意してください。
あくまでも、個々のユーザーは1人です。
1人のユーザーがたくさん投稿することがあっても、1つの投稿がたくさんのユーザーに紐づいているわけではないからです。そのため、マイクロポストモデル内に、
has_many :usersと記述するのは不適です。そのかわり、マイクロポストモデル内には
class Micropost < ApplicationRecord belongs_to :user validates :content, length: { maximum: 140 } end
belongs_to :userと記述します。
これで、マイクロポストはユーザーに所有されているという関係になりました。マイクロポストモデルには
user_idという属性を設定してあったので、自動的にuserモデルのIDと対応します。
- 投稿日:2019-07-09T12:39:50+09:00
[React.js]Rails on Rails上でモダンなフロント環境構築
はじめに
React公式チュートリアルに挑戦するべく、Railsサーバ上でReactを動作させる環境を構築していこうと思います!
Rails5.1からwebpackerやnpm,yarnなどに対応したため、それらを利用してReactを使えるようにします。
目次
- 1. yarnをインストールする
- 2. Railsプロジェクトを作成する
- 3. Gemfileの編集
- 4. webpack,reactをインストールする
- 5. 動作確認
前提環境
- cloud9 (amazon linux)
- Ruby 2.6
- Rails 5.1
- node 10.16
実践
1. yarnをインストールする
初めにyarnをインストールしておきます。
$ npm install -g yarn2. Railsプロジェクトを作成する
おなじみrails newしていきます。
ついでにディレクトリも作成したプロジェクトに変更しておきます。$ rails new webpack_test --skip-turbolinks && cd webpack_testturbolinksはJavascriptにおいて不具合の原因になりかねないので使用しません。
3. Gemfileの編集
webpacker gemをインストールするため、作成したプロジェクトフォルダ内のGemfileを編集します
~省略~ gem "webpacker"Gemfileを保存してから
bundle installしてください。4. webpack,reactをインストールする
webpackとreactをそれぞれインストールしていきます。
$ rails webpacker:install $ rails webpacker:install:reactそして最後に
HTMLヘッダーを以下のように編集します
javascript_include_tag→javascript_pack_tagjavascriptを呼び出すときwebpackerのヘルパータグで
<%=javascript_pack_tag'FILE_NAME'%>と記述します。app/views/layouts/application.html.erb<%= javascript_pack_tag 'application' %>5. 実際に動作させてみよう!
正常にインストールできていれば
app/javascript/hello_react.jsxが作成されていると思います。
reactはjsx内で動作しているので、jsxファイルを呼び出すことでreactを動かします。試しに、hello_react.jsxを表示させていこうと思います。
まずcontrollerとviewを作成しrouteを割り当てます。
rails g controller react_app indexconfig/routes.rbRails.application.routes.draw do get 'react_app/index' end作成したviewでjsxファイルを呼び出します。
view/react_app/index<%=javascript_pack_tag 'hello_react'%>rails サーバを起動して、正常に表示されるか確認します。
rails s
react_app/indexへ接続しHello React!と表示されていればReactの導入は完了です。6. Reactチュートリアルへの準備
まず、チュートリアル用に新しくjsxファイルを作っていきましょう。
app/javascript/pack/にtutorial.jsxを作成しておきます。
tutorial.jsx内にreactをimportします。tutorial.jsximport React from "react" import ReactDOM from "react-dom" //ここから下の行にチュートリアルの内容を記述していく実際にチュートリアルのスターターコードを
tutorial.jsxに記述して動作を確かめてみます。tutorial.jsximport React from "react" import ReactDOM from "react-dom" class Square extends React.Component { render() { return ( <button className="square"> {/* TODO */} </button> ); } } class Board extends React.Component { renderSquare(i) { return <Square />; } render() { const status = 'Next player: X'; return ( <div> <div className="status">{status}</div> <div className="board-row"> {this.renderSquare(0)} {this.renderSquare(1)} {this.renderSquare(2)} </div> <div className="board-row"> {this.renderSquare(3)} {this.renderSquare(4)} {this.renderSquare(5)} </div> <div className="board-row"> {this.renderSquare(6)} {this.renderSquare(7)} {this.renderSquare(8)} </div> </div> ); } } class Game extends React.Component { render() { return ( <div className="game"> <div className="game-board"> <Board /> </div> <div className="game-info"> <div>{/* status */}</div> <ol>{/* TODO */}</ol> </div> </div> ); } } // ======================================== ReactDOM.render( <Game />, document.getElementById('root') );
rails sを実行し、react_app/indexにアクセスしてみます。このままでは、デザインがおかしいのでスターターコードのcssを適応していきます。
app/assets/stylesheets/react_app.scssbody { font: 14px "Century Gothic", Futura, sans-serif; margin: 20px; } ol, ul { padding-left: 30px; } .board-row:after { clear: both; content: ""; display: table; } .status { margin-bottom: 10px; } .square { background: #fff; border: 1px solid #999; float: left; font-size: 24px; font-weight: bold; line-height: 34px; height: 34px; margin-right: -1px; margin-top: -1px; padding: 0; text-align: center; width: 34px; } .square:focus { outline: none; } .kbd-navigation .square:focus { background: #ddd; } .game { display: flex; flex-direction: row; } .game-info { margin-left: 20px; }もう一度
rails sを実行しreact_app/indexに接続すると
このような画面になっていればチュートリアルの準備は完了です。
あとがき
記事を書く経験が初めてでしたが、思ったより大変でした...。
分かりにくい箇所、至らない箇所があれば修正します。
- 投稿日:2019-07-09T12:24:42+09:00
Rails6 のちょい足しな新機能を試す49(consumes? 編)
はじめに
Rails 6 に追加されそうな新機能を試す第48段。 今回は、
consumes?編です。
Rails 6 では、ActiveSupport::Multibyte::Chars.consumes?を使うとDEPRECATION WARNINGが表示されるようになります。(私は自分で使ったこともないし、使われているところを見たことも無いのですが...)Ruby 2.6.3, Rails 6.0.0.rc1 で確認しました。Rails 6.0.0.rc1 は
gem install rails --prereleaseでインストールできます。$ rails --version Rails 6.0.0.rc1簡単なスクリプトを作る
今回は、動作確認用の簡単なスクリプトを書いて確認します。
bin/consumes.rb#!/usr/bin/env ruby require 'active_support/core_ext' puts '--- DEPRECATED WARNING ---' p ActiveSupport::Multibyte::Chars.consumes?('あ') puts '--- NO DEPRECATED WARNING ---' p 'あ'.is_utf8?Rails 6 では
実行すると
DEPRECATION WARNINGが表示されます。$ bin/duration.rb --- DEPRECATED WARNING --- DEPRECATION WARNING: ActiveSupport::Multibyte::Chars.consumes? is deprecated and will be removed from Rails 6.1. Use string.is_utf8? instead. (called from <main> at bin/consumes:5) true --- NO DEPRECATED WARNING --- true試したソース
試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try049_deprecated_consumes参考情報
- 投稿日:2019-07-09T11:01:33+09:00
method_sourceってgemを読んだら知恵が詰まってた。
method_source is 何?
minimum sample
require 'method_source' def my_important_method # do nothing, just sleep sleep 4 'successfuly done with my hard work!!' end method = method(:my_important_method) method.source.displayすると。。。
def my_important_method # do nothing, just sleep sleep 4 'successfuly done with my hard work!!' endメソッドの定義がプリントされる。
どんな実装か
Method objectからは定義もとのfile, lineが取れる。
そのファイルを全部読み込み、line以下を全て取ってくるlines = File.readlines(file) lines = lines[(line - 1)..-1]linesをイテレートして、methodの定義が終わるところを判定する。
lines.each do |v| code << v return code if complete_expression?(block ? block.call(code) : code) endこれでmethod定義が抜き出せたので、あとは表示するだけ
知恵
rescueされるerrorを判別するだけのmodule
def hoge rescue MyModule end module MyModule def self.===(error) some_condition(error) end endevalを使ってstrの構文をチェックだけして、BEGIN throwで実行させずに戻る
catch(:valid) do eval("BEGIN{throw :valid}\n#{str}") endどうゆう仕組みか?
strが構文としておかしいとSyntaxErrorが出て throwされない。
strが構文としてokだったらそのstr実行前に BEGIN で登録された throwが走る。所感
まず
BEGINとか知らなかった。
この3行でこれだけのこと詰め込めるrubyはスマートで好き。
- 投稿日:2019-07-09T09:46:33+09:00
Ruby で [-1, -2, -3].map(&:succ >> :to_s) という感じで書きたい
[-1, -2, -3].map(&:succ >> :to_s)という関数型を意識した記述
&を使いブロック渡しで任意のオブジェクトを渡す仕組みがあります。
カラクリについては https://qiita.com/hamajyotan/items/f2a96bbb1ccc60a06053 に記述。[-1, -2, -3].map(&:succ) #=> [0, -1, -2]上記記述に対して、
Proc#>>と同じ要領でsuccを実施した結果に更にto_sを実施できたら嬉しいですね。
けど、できません。。![]()
この記事はこれをできるようにするための実装の話です。[-1, -2, -3].map(&:succ >> :to_s) #=> NoMethodError: undefined method `>>' for :succ:SymbolProc#>> および Proc#<<
Ruby 2.6 から、 Proc#>> および Proc#<< が追加されました。いわゆる関数合成と言われる仕組みです。
f1 = -> x { x.succ } f2 = -> x { x.to_s } f3 = f1 >> f2 f3.call(-3) # f1 の実行結果を f2 の引数として渡す。 f2.call(f1.call(-3)) #=> "-2" f4 = f1 << f2 f4.call(-3) # >> とは逆順に合成される。 f1.call(f2.call(-3)) #=> "-4"Symbol#>> と Symbol#<< があったら嬉しい
自分自身を
to_procにより Proc オブジェクトに変換、そこに更に>>で合成すればよさそうです。# >> および << メソッドを生やす module SymbolComposeToLeftAndRight def >>(g) to_proc >> g end def <<(g) to_proc << g end end Symbol.prepend(SymbolComposeToLeftAndRight) # どうだ!?。。。残念 [-1, -2, -3].map(&:succ >> :to_s) #=> NoMethodError: undefined method `call' for :to_s:Symbolどうやら
Proc#>>の引数に対してcallを要求しているようです。Proc の >> および << の引数側も to_proc するようになれば嬉しい
Proc#>>およびProc#<<の引数は Proc オブジェクトであることが期待されています。
もう少し正確に言うと、callに反応するオブジェクトであることが期待されています。class Callable def call(x) x + 5 end end proc1 = proc { |x| x + 1 } proc2 = proc1 << Callable.new # 引数に 1加算され、更にその結果に 5加算。 proc2.call(3) #=> 9ここが拡張されて、引数自体に
to_procがかかってから既存の処理となるようにならないでしょうか?
言い換えると、.callを期待するオブジェクト改め、.to_proc.callを期待するオブジェクトと言っても良いです。module ProcComposeToLeftAndRightWithToProc def >>(g) super(g.to_proc) #=> 引数オブジェクトを to_proc してから既存の処理 end def <<(g) super(g.to_proc) end end Proc.prepend(ProcComposeToLeftAndRightWithToProc)これで上記エラーも回避できるはず。
実装した (まとめ)
module ProcComposeToLeftAndRightWithToProc def >>(g) super(g.to_proc) end def <<(g) super(g.to_proc) end end Proc.prepend(ProcComposeToLeftAndRightWithToProc) module SymbolComposeToLeftAndRight def >>(g) to_proc >> g end def <<(g) to_proc << g end end Symbol.prepend(SymbolComposeToLeftAndRight) # succ してから to_s [-1, -2, -3].map(&:succ >> :to_s) #=> ["0", "-1", "-2"] # succ してから to_s, さらに length [-1, -2, -3].map(&:succ >> :to_s >> :length) #=> [1, 2, 2] # 逆側の合成。 to_s してから succ [-1, -2, -3].map(&:succ << :to_s) #=> ["-2", "-3", "-4"]関数型っぽい!
既存 2.6 とも互換はあるし、 Ruby の自体がこうなってたら嬉しい人は少なくないんじゃないかと思うけどどうでしょう?
- 投稿日:2019-07-09T08:47:07+09:00
ruby snmpでbulkwalkの習作
Rubyでbulkwalkするスクリプトを組んでみた。
ネットワーク内に存在する大量装置にsnmpbulkwalkするスクリプトを従来Perlで作ってたんだけど、rubyで作り直してみた。
取得回数が限られているbulkwalkであればruby-snmpのExamplesにあったんだけど、同一ツリー内を再帰取得するコードが見当たらなかったので書いておきます。
- v1の装置があることも考慮し、v1であればwalk、v2cであればget_bulkします。
- 応答結果は「oid値」「応答値」「タイプ」を配列で回答します
- ホスト単位にMIB値を連続取得します。ホスト単位にパラレルにしてもいいかも。
snmpbulkwalk.rb#! /usr/local/bin/ruby require 'snmp' class SNMPWALK @@array = Array.new def self.bulk(hostname:,community:'public',oid:,max_rep:10) SNMP::Manager.open(:Host => hostname , :Community => community) do |manager| next_oid = oid while next_oid.subtree_of?(oid) do response = manager.get_bulk(0,max_rep.to_i,next_oid) response.each_varbind do |r| next_oid = r.name break if !next_oid.subtree_of?(oid) @@array.push([r.name.to_a.join('.'),r.value.to_s,r.value.asn1_type]) end end end return @@array end def self.walk(hostname:,community:'public',oid:) SNMP::Manager.open(:Host => hostname , :Community => community) do |manager| next_oid = oid manager.walk(next_oid) do |response| response.each do |r| @@array.push([r.name.to_a.join('.'),r.value.to_s,r.value.asn1_type]) end end end return @@array end end ##################################################################################### ## get_mibdata Main ##################################################################################### ['host_a','host_b','host_c'].each do |host| ['1.3.6.1.2.1.2.2.1.1','1.3.6.1.2.1.2.2.1.7'].each do |mib| oid = SNMP::ObjectId.new(oid) if !oid.kind_of?(SNMP::ObjectId) result = "" if mib['snmp_version'] == 'v1' result = SNMPWALK.walk(hostname:host,community:'public',oid:mib) else result = SNMPWALK.bulk(hostname:host,community:'public',oid:mib) end p result end end自作コードをQiitaに書いたの初めてなので突っ込み歓迎です。
- 投稿日:2019-07-09T08:47:07+09:00
ruby snmpでbulkwalk
Rubyでbulkwalkするスクリプトを組んでみた。
ネットワーク内に存在する大量装置にsnmpbulkwalkするスクリプトを従来Perlで作ってたんだけど、rubyで作り直してみた。
取得回数が限られているbulkwalkであればruby-snmpのExamplesにあったんだけど、同一ツリー内を再帰取得するコードが見当たらなかったので書いておきます。
- v1の装置があることも考慮し、v1であればwalk、v2cであればget_bulkします。
- 応答結果は「oid値」「応答値」「タイプ」を配列で回答します
- ホスト単位にMIB値を連続取得します。ホスト単位にパラレルにしてもいいかも。
snmpbulkwalk.rb#! /usr/local/bin/ruby require 'snmp' class SNMPWALK @@array = Array.new def self.bulk(hostname:,community:'public',oid:,max_rep:10) SNMP::Manager.open(:Host => hostname , :Community => community) do |manager| next_oid = oid while next_oid.subtree_of?(oid) do response = manager.get_bulk(0,max_rep.to_i,next_oid) response.each_varbind do |r| next_oid = r.name break if !next_oid.subtree_of?(oid) @@array.push([r.name.to_a.join('.'),r.value.to_s,r.value.asn1_type]) end end end return @@array end def self.walk(hostname:,community:'public',oid:) SNMP::Manager.open(:Host => hostname , :Community => community) do |manager| next_oid = oid manager.walk(next_oid) do |response| response.each do |r| @@array.push([r.name.to_a.join('.'),r.value.to_s,r.value.asn1_type]) end end end return @@array end end ##################################################################################### ## get_mibdata Main ##################################################################################### ['host_a','host_b','host_c'].each do |host| snmp_version = "v2c" ['1.3.6.1.2.1.2.2.1.1','1.3.6.1.2.1.2.2.1.7'].each do |mib| oid = SNMP::ObjectId.new(oid) if !oid.kind_of?(SNMP::ObjectId) result = "" if snmp_version == 'v1' result = SNMPWALK.walk(hostname:host,community:'public',oid:mib) else result = SNMPWALK.bulk(hostname:host,community:'public',oid:mib) end p result end end自作コードをQiitaに書いたの初めてなので突っ込み歓迎です。
- 投稿日:2019-07-09T02:29:53+09:00
kaminariのgemを用いたページネーションの実装方法
ページネーションとは、長い文章を複数のページに分割して、各ページへのリンクを並べアクセスしやすくすること。
https://gyazo.com/7acc560088bf6fb2c04b90dda3b3d38e実装手順
1.kaminariのGemをインストールしてサーバーを立ち上げ直す
Gemfileの最後の行にgemを記述する。
gem 'kaminari'Gemをインストールする。
$ bundle installrails s(サーバー)を立ち上げ直す。
rails s2.コントローラファイルを編集する
kaminariのgemをインストールすることで使えるメソッド
1.pageメソッド
params[:page]2.perメソッド
1ページあたりに表示する件数を指定するメソッドである。per(1ページあたりに表示する件数)3.「page」と「per」メソッドを利用して、コントローラに記述すると以下のようになる。
def index @tweets = Tweet.includes(:user).page(params[:page]).per(5).order("created_at DESC") end3.ビューファイルを編集する
paginateメソッド
ページネーションのリンクを表示したいときに使用するメソッドである。paginate(インスタンス変数)ビューファイルにはルビータグで囲って使用する。
<div class="contents row" > <% @tweets.each do |tweet| %> <div class="content_post" style="background-image: url(<%= tweet.image %>);"> <%= simple_format(tweet.text) %> <span class="name"><%= tweet.name %></span> </div> <% end %> <%= paginate(@tweets) %> </div>
- 投稿日:2019-07-09T02:22:25+09:00
RSpecのfeatureテストでsessionを扱う方法
環境
- macOS 10.14.5
- ruby 2.5.5
- rails 5.2.3
はじめに
RailsチュートリアルのテストをRSpecで書いていた時にあることに気づきました。
featureテストではsessionが使えない!?
Railsチュートリアル8章のテストでis_logged_in?というユーザーがログイン中かどうかを論理値で返すテスト用ヘルパーを紹介していました。
test/test_helper.rb# テストユーザーがログイン中の場合にtrueを返す def is_logged_in? !session[:user_id].nil? endなので同様に
spec/support/test_helper.rbに記述してfeatureテストでヘルパーを使用した。
(ヘルパーを定義する方法はこちらを見るとよいと思います
→ マクロ(ヘルパーメソッド)を定義してフィーチャースペックのユーザー切替えを楽に行う
)spec/support/test_helper.rbmodule TestHelper def is_logged_in? !session[:user_id].nil? end endspec/features/users_signup_spec.rbrequire 'rails_helper' RSpec.feature "UsersSignups", type: :feature do feature "valid signup information" do before do visit signup_path fill_in "Name", with: "Example User" fill_in "Email", with: "user@example.com" fill_in "Password", with: "password" fill_in "Confirmation", with: "password" end scenario "add users count" do expect { click_button "Create my account" expect(page).to have_current_path user_path(User.last) }.to change(User, :count).by(1) end scenario "show flash message" do click_button "Create my account" expect(page).to have_content "Welcome to the Sample App!" visit current_path expect(page).to_not have_content "Welcome to the Sample App!" end scenario "login created user" do click_button "Create my account" expect(is_logged_in?).to be_truthy #### ここで使用 #### end end feature "invalid signup information" do before do visit signup_path fill_in "Name", with: "" fill_in "Email", with: "user@invalid" fill_in "Password", with: "foo" fill_in "Confirmation", with: "bar" end scenario "no difference users count" do expect { click_button "Create my account" expect(page).to have_current_path signup_path }.to_not change(User, :count) end scenario "is show error messages" do click_button "Create my account" expect(page).to have_content "Name can't be blank" expect(page).to have_content "Email is invalid" expect(page).to have_content "Password is too short" expect(page).to have_content "Password confirmation doesn't match Password" end end endするとこんなエラーが、、、
1) UsersSignups valid signup information login created user Failure/Error: !session[:user_id].nil? NameError: undefined local variable or method `session' for #<RSpec::ExampleGroups::UsersSignups::ValidSignupInformation:0x00007fe38a4a3e20> # ./spec/support/login_macros.rb:3:in `is_logged_in?' # ./spec/features/users_signup_spec.rb:30:in `block (3 levels) in <top (required)>' # -e:1:in `<main>'解決策
どうやら調べてみるとfeatureテスト内ではsesssionが扱えないようで、コントローラーテスト内では使えるみたい。
でもどうにかfeatureテスト内でこのヘルパーを使えるようにする方法はないかと調べていたところある記事を見つけました。
Rails feature testing with logged in user (undefined method 'session')
'rack_session_access'というgemを使うとfeatureテスト内でもsessionを参照したり、変更したりできるみたいなのでgemのREADMEを参考にセットアップしました。Gemfilegem 'rack_session_access' # 追加$ bundle install # gemをインストールconfig/environments/test.rbRails.application.configure do : : config.middleware.use RackSessionAccess::Middleware # 追加 endspec/spec_helper.rbrequire "rack_session_access/capybara" # 追加このgemを使うとsessionに値を挿入することもできるらしいが今回は値が入っているかどうかを調べたいだけなので以下のメソッドを記述してRailsチュートリアルに習って論理値を反転。
spec/support/test_helper.rbmodule TestHelper def is_logged_in? !page.get_rack_session_key('user_id').nil? # 変更 end endはじめは
get_rack_session_key(:user_id)と修正したがダメだったのでREADEMEを見ると、文字列('user_id')を渡さなきゃいけないらしいまとめ
'rack_session_access'gemを使うとfeatureスペックでもsessionを扱える!しかし頻繁にsessionの操作をfeatureスペック内で行わないようなら、ログインしているかどうかをテストする方法は他にもいくらでもあるのでgemをわざわざ入れる必要はないかも。。
- 投稿日:2019-07-09T02:00:58+09:00
[考えてみた]セッション変数から素直?に値を取り出したい
nilか?明示的に調べる方法
こんな感じの実装を見かけることがあります。
session[:hoge] == nilだったときに備えているわけです。if session[:hoge] fuga = session[:hoge][:fuga] piyo = session[:hoge][:piyo] endしかし、ifを読むと、ビジネスロジック的になにか意味があるのかな?と思えてしまうので、プログラムの都合のifはなるべく減らして、なるべくビジネスロジックだけに集中した書き方をしたいです。
nilか?を暗黙のうちに済ます方法
rubyにはぼっち演算子(&.)というレシーバがnilのときはnilを返してくれる演算子があります。素直か?というと少し微妙かもしれませんが、Hash#digを使うことで、ifを減らしてロジックな素直に書くことができそうです。
fuga = session.dig(:hoge,:fuga) piyo = session.dig(:hoge,:piyo)
(追記)
..と思いましたが、with_indifferent_accessを途中に入れないと、nilが帰ってきてしまう。fuga = session.with_indifferent_access.dig(:hoge,:fuga) piyo = session.with_indifferent_access.dig(:hoge,:piyo)
with_indifferent_accessはHashのサブクラスなので、to_hでもいいというか、そもそもセッションはHashのサブクラスなのだが、、、ちょっと要調査です。
- 投稿日:2019-07-09T00:58:18+09:00
ある社内SEのリストーラ?とRuby on Railsを学ぶための本ご紹介
はじめに
こんばんは。
大手SIer → ブラック → ブラック → ヤクザブラック → グレーだけど潰れそう → リストーラ?
という経歴を渡り歩いているとある社内SEのお話です。それは唐突に
定時後、社長から呼び出しがかかりました。
まあ会社が今大変うんぬん。。。
赤字うんぬん。。。で一通り話したあと、うーんと考えて
社長曰く、「今は転職活動やってる?」
いや、え?
あれ、これリストラ的なやつ?
とりあえず素直にそういうことは今はやっていないけど、常に危機意識はあります。
という模範解答をとまどいつつも出す。からなぜかスルーされて
いつも通り、経理のおじいちゃんの愚痴が始まって、
お金の動き分からないうんぬん。。。
給料払い過ぎかなうんぬん。。。
リストラとかも考えなうんぬん。。。あ、いまリストーラ言ったよね
レベル23くらいで覚えそうなやつ。
とりあえず、適当に相槌打って素直に聞いてみた。
「僕は早めに出て行ったほうがいいってことですかね?」以下、社長のお言葉
いや、そんなこと言ってるわけじゃないよ~!!(てへぺろ)
残ってほしいし、頑張ってほしいって思ってるよ~!!
でもほら転職しそうだったら、引継ぎとか考えないかんし~!!(もじもじ)
給料に見合った結果をね~。ボーナスは契約上仕方なく出すけど。(いやいや)
僕のサラリーマン時代はね~。ボーナスなんてなかったし。苦しいサラリーマン時代だったし。(いらいら)
会社赤字だけど、僕(社長)の給料は下げないよー。でも社員は実績に応じて!きりっ!あ、引継ぎ考えてるのね。今目の前に僕いますけど。
入社時約束した通り、ボーナスは出るみたいです。ただ、コスト的に割高と判断されているようで、
まあ、野球選手の高年棒?ベテラン選手みたいな扱いをまさに受けています。
色々周りの話を聞いてみると、過去から今の私のポジションを3人ほど潰しているようです。
詳細書くとあれなんで、省略しますが。とりあえず僕、4人目。
ちなみにこのポジションにつくのも過去から数えて4人目。
あ、打率10割のやつやん。。。・・・ということで、かなり長くなったので続きはまた後日書くとして、本題の
Rubyを学ぶ人、Ruby On Railsを学ぶ人へ本のご紹介
プロを目指す人のためのRuby入門
Railsやるなら、上の本は必ず読んだほうがいい。仕様が簡潔にまとまっているし、読みやすい。
すぐにRailsでアプリを作り始めるより、まずは上記の本でRubyの仕様を理解すると、
詰まった時に大いに役立つ。いわゆるコピペで動かない問題への対応。
仕様を理解しておかないと、コード読めなくてなんで詰まったかすら分からないから。
難しいところやめんどくさいところは飛ばしてOK。私はテスト周りや正規表現、最後らへんの章は飛ばしました。
他の言語から入ってきたので、ほんとによくできてる言語だなと感心しました。
とくに型の排除、式の結果自体が返り値になる(if文書くとよく分かります)、
メソッドチェーンって言うんだっけ?コロンでつなげるやつ、ループ周り
強力なORマッパー的なやつSQL書かずにコードだけでDBのトランザクション発行できる。(これはRailsか。)で、次に
改訂4版 基礎 Ruby on Rails (IMPRESS KISO SERIES)
立ち読みして、サンプルが分かりやすく書かれてたので買い。これが良かった。
動くアプリを真似ながら習得するのが一番早いので、私は必要な部分を真似して習得しました。
Google先生とこの本が5体5って感じ。
あ、ちなみにRailsアプリはscaffoldが推奨されているのをよく見ますが、お勧めしません。
だって意味が分からないまま、動いてしまうからです。
ルートも1つ1つ書いたほうがよいと思います。汚くてもいいから自分の書き方で書く。動けばいいの精神で。
ここでまっとうなやり方にこだわっていたら、私は挫折していたと思います。
あとでまっとうなやり方を学んでソースコードをリファクタリングすればよいのです。自分の書き方で書いていれば、
リファクタリングもほんとにスムーズにいきます。びっくりするくらい。
また、ルートをしっかり書こうとすると、RESTFULな考えを自然に覚えさせられます。それが分かれば、scaffold
使ってもいいかなと。だってscafflodってRESTFULな感じでCRUD操作を簡単に実装してくれるやつだし。あとはRails 〇〇 でぐぐって、ひたすらソースコードを真似る。
です。これでWebサービスを1つ作ることができました。
(検証・本番環境の構築も激しく詰まったけど、また後日書きます)蛇足ですが、本のお勧め読み方
ある程度分からなくてもいい、適当でもいいから、まず斜め読みで全部読む。
それから手を動かしながら本のソースコードを書くといい感じ。
この前東大生が言ってた。本を読んで最初から100%理解できるわけないと。
まず斜め読みして全部の20%把握してから(たぶん東大生は70%くらいだと思うけど)、
もっかいしっかりやったほうがはるかに効率よいと。
実践してみたら、ほんとでした。高校生の頃にこの真理を学んでおけば。。。と悔やむくらい。
20%把握しておけば、これは難しいからあとでいいやとか、これは大事だからしっかりとかもある程度
事前に分かっているから、とても効率よいのです。本を読むぞって構えなくてもいいのも〇。隙間時間でざっとね。
最後にしっかり時間とってやる。章ごとくらいが集中力続く限界かな。
だまされたと思ってお試しあれ。
- 投稿日:2019-07-09T00:58:18+09:00
ある社内SEと初心者向けRuby on Rails関連の本ご紹介
Rubyを学ぶ人、Ruby On Railsを学ぶ人へ本のご紹介
プロを目指す人のためのRuby入門
Railsやるなら、上の本は必ず読んだほうがいい。仕様が簡潔にまとまっているし、読みやすい。
すぐにRailsでアプリを作り始めるより、まずは上記の本でRubyの仕様を理解すると、
詰まった時に大いに役立つ。いわゆるコピペで動かない問題への対応。
仕様を理解しておかないと、コード読めなくてなんで詰まったかすら分からないから。
難しいところやめんどくさいところは飛ばしてOK。私はテスト周りや正規表現、最後らへんの章は飛ばしました。
他の言語から入ってきたので、ほんとによくできてる言語だなと感心しました。
とくに型の排除、式の結果自体が返り値になる(if文書くとよく分かります)、
メソッドチェーンって言うんだっけ?コロンでつなげるやつ、ループ周り
強力なORマッパー的なやつSQL書かずにコードだけでDBのトランザクション発行できる。(これはRailsか。)で、次に
改訂4版 基礎 Ruby on Rails (IMPRESS KISO SERIES)
立ち読みして、サンプルが分かりやすく書かれてたので買い。これが良かった。
動くアプリを真似ながら習得するのが一番早いので、私は必要な部分を真似して習得しました。
Google先生とこの本が5体5って感じ。
あ、ちなみにRailsアプリはscaffoldが推奨されているのをよく見ますが、お勧めしません。
だって意味が分からないまま、動いてしまうからです。
ルートも1つ1つ書いたほうがよいと思います。汚くてもいいから自分の書き方で書く。動けばいいの精神で。
ここでまっとうなやり方にこだわっていたら、私は挫折していたと思います。
あとでまっとうなやり方を学んでソースコードをリファクタリングすればよいのです。自分の書き方で書いていれば、
リファクタリングもほんとにスムーズにいきます。びっくりするくらい。
また、ルートをしっかり書こうとすると、RESTFULな考えを自然に覚えさせられます。それが分かれば、scaffold
使ってもいいかなと。だってscafflodってRESTFULな感じでCRUD操作を簡単に実装してくれるやつだし。あとはRails 〇〇 でぐぐって、ひたすらソースコードを真似る。
です。これでWebサービスを1つ作ることができました。
(検証・本番環境の構築も激しく詰まったけど、また後日書きます)蛇足ですが、本のお勧め読み方
ある程度分からなくてもいい、適当でもいいから、まず斜め読みで全部読む。
それから手を動かしながら本のソースコードを書くといい感じ。
この前東大生が言ってた。本を読んで最初から100%理解できるわけないと。
まず斜め読みして全部の20%把握してから(たぶん東大生は70%くらいだと思うけど)、
もっかいしっかりやったほうがはるかに効率よいと。
実践してみたら、ほんとでした。高校生の頃にこの真理を学んでおけば。。。と悔やむくらい。
20%把握しておけば、これは難しいからあとでいいやとか、これは大事だからしっかりとかもある程度
事前に分かっているから、とても効率よいのです。本を読むぞって構えなくてもいいのも〇。隙間時間でざっとね。
最後にしっかり時間とってやる。章ごとくらいが集中力続く限界かな。
だまされたと思ってお試しあれ。
- 投稿日:2019-07-09T00:27:34+09:00
WindowsでRuby/GTK3を実行する
MacやLinuxの場合,
gem install gtk3
でインストールできるらしいのですが,Windowsだと少し面倒なのでメモ.RubyInstaller for Windows をダウンロード
- 以下からRubyInstallerをダウンロードします.
- 以後 rubyinstaller-2.6.3-1-x64.exe をダウンロードしたものとして説明します.
ダウンロードしたrubyinstaller-2.6.3-1-x64.exeを実行
MSYS2をインストール
GTK3のインストール
- コマンドプロンプトを開き,インストールしたRuby環境を用いて,GTK3をインストールします.
> cd C:\Ruby26-x64\bin > gem install gtk3動作確認
- 以下のコードを任意の場所へ保存します.
test.rb#!ruby -w require "gtk3" cWindow = Gtk::Window.new() cWindow.signal_connect(:destroy){Gtk.main_quit()} cWindow.show() Gtk.main()
- インストールしたRuby環境でtest.rbを実行します.
> C:\Ruby26-x64\bin\ruby.exe test.rb
- 投稿日:2019-07-09T00:24:38+09:00
CRUD機能のD(Delete)におけるデータベース間とのやりとり
CRUD機能とは、ほぼ全てのソフトウェアが有する4つの永続的な基本機能の頭文字をそれぞれ並べた用語のことをいう。 その4つの機能とは、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)を指す。
今回は、DのDeleteについての仕組みを解説する。そのため、主にコントローラのdestroyアクションについて解説する。Deleteは、既にデータベースに存在するデータを削除することである。Deleteの流れは、destroyアクションのみを実装すれば良い。
Deleteの処理の流れ
削除したいデータをデータベース上の特定テーブルから抽出して削除する処理
ルーティングを設定する。
delete 'tweets/:id' => 'tweets#destroy'destroyアクションを作動させるためのhttpメソッドは、deleteを用いる。
コントローラを設定する
def destroy tweet = Tweet.find(params[:id]) if tweet.user_id == current_user.id tweet.destroy end endコントローラの記述は、editアクションやupdateアクションのときと同様削除したいデータのidと現在ログイン中のユーザーのidが一致していれば、抽出したデータを削除するという処理を行う。
ちなみに、if文を1行に省略して記述する方法として、後置ifを用いて記述する方法がある。
def destroy tweet = Tweet.find(params[:id]) tweet.destroy if tweet.user_id == current_user.id end
- 投稿日:2019-07-09T00:08:37+09:00
CRUD機能のU(Update)におけるデータベース間とのやりとり
CRUD機能とは、ほぼ全てのソフトウェアが有する4つの永続的な基本機能の頭文字をそれぞれ並べた用語のことをいう。 その4つの機能とは、Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)を指す。
今回は、UのUpdateについての仕組みを解説する。そのため、主にコントローラのeditアクションとupdateアクションについて解説する。Updateは、既にデータベースに存在するデータを新たに更新することである。Update処理の流れとしては、editアクション→updateアクションの順番となる。
1.Updateの処理の流れ
データベース上既に存在する特定のデータを抽出する処理(editアクション)
↓
抽出したデータを更新し、再びデータベースに保存する処理(updateアクション)2.データベース上既に存在する特定のデータを抽出する処理(editアクション)
データを更新するためには、編集画面に移動する必要がある。
ルーティングを設定する。
get 'tweets/:id/edit' => 'tweets#edit'コントローラを設定する
def edit @tweet = Tweet.find(params[:id]) endeditアクションは、データベースの特定のテーブルから,編集したいレコード(ここでは、ツイートのid)を抽出する。そして、そのデータを編集画面のビューに送る。
3.抽出したデータを更新し、再びデータベースに保存する処理(updateアクション)
editアクションによって呼び出された編集画面に新規投稿する。その際、ビューの方であらかじめ、ルーティングが呼び出される記述をする。(今回は、form_tagを使う。)
<%= form_tag("/tweets/#{@tweet.id}", method: :patch ) do %>これにより、編集をして新規投稿した時にルーティングが呼びだされる。ちなみに、編集をする際に使用するhttpメソッドはpatchである。
ルーティングの設定
patch 'tweets/:id' => 'tweets#update'これにより、新規投稿した時にコントローラのupdateアクションが実行するようになる。
コントローラの設定
def update tweet = Tweet.find(params[:id]) if tweet.user_id == current_user.id tweet.update(tweet_params) end endupdateアクションは、編集するデータがログイン中のユーザーであれば、編集されたデータを新規投稿を行い、テーブルに新たなレコードを保存するようになる(データベースとのやりとりにおいては、createアクションと同じ動きをする。)
ちなみに、if文を1行に省略して記述する方法として、後置ifを用いて記述する方法がある。
def update tweet = Tweet.find(params[:id]) tweet.update(tweet_params) if tweet.user_id == current_user.id end
- 投稿日:2019-07-09T00:08:07+09:00
あなたはRailsチュートリアルで一体なにを学んだというのか【1章】
注意:プログラミング歴29日の初心者が書いています
注意:間違っていたら優しく教えてください(喜びます)
1.2.1 開発環境
開発環境ってなんですか
「開発」っていうのはつまりコードを書いて何か作るってことです。
「環境」っていうのはつまりコードを書くための準備環境のことです。(トートロジー)『自分のパソコンで黒い画面とか、エディタ(コード書くアプリのこと)とか使って「開発」してもいいけど、あなたがどんなパソコンでどんなエディタ使ってるのかわからないから、「IDE」で統一してチュートリアルすすめようね』ということです。
「IDE」ってなんですか
ネット上であなたのパソコンの代わりをやってくれます。
『チュートリアルを、みーんなおんなじパソコン使ってやろうね』ってことです。
「AWS Cloud9」っていう名前がついてます。アマゾンが、インターネット上であなたにパソコンを貸してくれています。無料なのでとりあえず借りときましょう。「Cloud9」の初期登録はググるしかないです。わからなかったらとにかくググるしかないです。検索力も大事らしいです。
登録がおわったら、早速cloud9を開く。
「ファイルとかフォルダが表示された画面」と、「ファイルの中身を表示する画面」と「ターミナル」にわかれています。
「ファイルとかフォルダが表示された画面」: あなたのパシコンでいうところの「エクスプローラ」とか「ファインダー」と同じです。
「ファイルの中身を表示する画面」: ファイルの中身を表示する画面です。
「ターミナル」: あなたのパソコンでいうところの「黒い画面」と同じです。
「ターミナル」ってなんですか
映画で悪いハッカーとかがいじってる「黒い画面」のことです。必ずしも黒である必要はないです。
昔のパソコンはマウスとかカーソル(矢印)がなかったから、文字を直接打ち込んでファイルを作ったりコピーしたりしていたらしい。(知らんけど)
その名残。
現代では、発展的な内容をするときは、黒い画面に文字を打ち込んでパソコンを操作します。
「Cloud9」では、色が黒くなくなって怖さが減っています。1.2.2 Railsをインストールする
インストールしないと使えません。
「Rails」は元々あなたが持っているものではありませんので、インターネットからダウンロードして使います。
ただし、ダウンロードしかたらといってどこかにわかりやすく表示されるわけではありません。
でも、チュートリアルの通りにすれば使えるようになっているらしいので、ひとまずよしとしてください。1.3 最初のアプリケーション
cd environment に
$rails newでプロジェクト作成「アプリケーション」ってなんですか
全部アプリです。パズドラもアプリ、ウェブサイトもアプリ、Webサービスもアプリ、ホームページもアプリ、これからは全部アプリと呼びます。
「ディレクトリ」ってなんですか
「フォルダ」のことです。これからは「ディレクトリ」と呼びます。
「新しいフォルダを作る」したり、コピーしたり削除したり、今後はターミナルに「コマンド(命令)」を打ち込んで操作することを覚えます。(最初から全部暗記するのは無理なので徐々に覚えればいいと思います)「rails new」するってなんですか
「rails new」 するとディレクトリとファイルが自動でいっぱい出てきます。「Rails君」が勝手に全部作りました。「Rails君」がいなかったら、あなたが全部作るハメになっていました。
それと、「Rails君」がいつも決まった名前を各ディレクトリに付けてくれるおかげで、みんながわかりやすい名前になってます。わからないのは勉強を始めたばかりのあなただけです。
1.3.1 「Bundler」「gem」ってなんですか
「gem」: 追加機能のことです
「bundler」: 追加機能をまとめて管理するやつのことです。
「rails new」 したときに「Rails君」が勝手にいろんな追加機能(gem)を入れてます。チュートリアルでは、いるものといらないものを整理するように言っています。
1.3.2 rails serverってなんですか
これするとアプリケーションが動きます。(ちがうけどそうだと思います)
1.3.3 Model-View-Controller (MVC)ってなんですか
アプリケーションを構成する3銃士です。
「Model」: データベース担当です
「View」: 画面表示担当です
「Controller」: 指示担当です(例えば、ログイン画面にアクセスしたらちゃんとログイン画面が表示されるのはコントローラが指示してるからです。コントローラが間違っていたら違う画面が表示されます)
1.4 Gitによるバージョン管理
「ヤベー!間違えたー!」 とか
「あ、これ3日前の状態まで戻さないと無理だわコレ」っていうときに戻せるように、こまめにセーブデータを作っておくことです。
これを自分でやるとめちゃ大変なのでgitという仕組みで管理します。gitの管理下に置く
$git initリポジトリの初期化
$git add -A新しいファイルをgit対象に
$git commit -m "initialize repository"コミットとコミットメッセージ「リポジトリ」「コミット」ってなんですか
「リポジトリ」: セーブデータの保存場所です
「コミット」: セーブです
「git add -A」 :変更のあったファイルを「セーブ対象」として登録します
1.4.3 Bitbucket
dropboxとかgoogleドライブとかと同じです。自分のパソコンだけじゃなくて、ネット上に保存しておくと、他の人も見れるので便利です。チームで開発するときにも便利です。
それと、あなたのパソコンが壊れたときでもデータは無事です。bitbusketに新しいリモートリポジトリ作成
bitbusketのサイトから新しいリポジトリの作成を選択
$git remote add origin 自分のアドレス@bitbucket.org:username/アプリ名.git:gitにadd
$push -u origin --all:bitbucketリポジトリにプッシュ「ssh」とか「公開鍵」ってなんですか
「ssh」: 遠隔操作のことです。あなたのcloud9をbitbucketで遠隔操作でデータ保存したりします。
「公開鍵」: 遠隔操作するための鍵です。知らない人に遠隔操作されたら怖いので、普段は鍵がかかってます。
「ブランチ」「マージ」ってなんですか
(master)ってなっているのが、一番大事な元セーブデータです。
元セーブデータをいじると、間違ったときに大変なので、別のセーブデータにコピーして、そっちで変更するなり作業します。それで上手くいったら、元セーブデータと合体(マージ)させます。
「プッシュ」ってなんですか
Bitbucketにデータを保存することです。アップロードみたいなものです。
1.5 デプロイする
ネットに公開するっていうことです。
「Heroku」というサービスを使うとが簡単で便利なのでぜひ使いましょう。ターミナルでheroku CLIにログイン
$ heroku login --interactiveパスワード入力ヘロクに登録して、Cloud9からログインして、プッシュすると、あら不思議。
もうあなたのアプリケーションは世界中から見ることができちゃいます。herokuにアプリケーションを作成してプッシュ
$ heroku create:自動でherokuに新規アプリケーション作成
$ git push heroku master:herokuにプッシュまとめ
cd environment に
$rails newでプロジェクト作成gitの管理下に置く
$git initリポジトリの初期化
$git add -A新しいファイルをgit対象に
$git commit -m "initialize repository"コミットとコミットメッセージbitbusketに新しいリモートリポジトリ作成
bitbusketのサイトから新しいリポジトリの作成を選択
$git remote add origin 自分のアドレス@bitbucket.org:username/アプリ名.git:gitにadd
$push -u origin --all:bitbucketリポジトリにプッシュターミナルでheroku CLIにログイン
$ heroku login --interactiveパスワード入力herokuにアプリケーションを作成してプッシュ
$ heroku create:自動でherokuに新規アプリケーション作成
$ git push heroku master:herokuにプッシュ



















