- 投稿日:2020-11-30T23:21:39+09:00
第10回(1)、Rubyでフィボナッチ数列
フィボナッチ数列
本記事は大学院前期過程の講義[マルチスケールシミュレーション特論]に関する記事です
フィボナッチ数列はあの有名な数列。それをRubyで求める。(第n項を求める)TDD
この講義はテスト駆動開発に従っているので、それに従っていきます。
第0項(初項)
フィボナッチ数列の初項は0。
p fib(0)fibって何?って怒られる。defしましょう。
def fib(n) if n==0 return 0 end end p fib(0)ここで、前回の記事にて作成した assert_equal を用いて、期待値と出力を比較確認。
require './assert_equal' def fib(n) if n==0 return 0 end end assert_equal(0, fib(0))実行する。
expected :: 0 result :: 0 succeeded in assert_equal.そらこうなる。
第1項
フィボナッチ数列の第1項は1。まずは以下のようにテストの部分だけ追加してみる。
require './assert_equal' def fib(n) if n==0 return 0 end end assert_equal(0, fib(0)) assert_equal(1, fib(1))もちろん失敗。
require './assert_equal' def fib(n) if n==0 return 0 end if n==1 return 1 end end assert_equal(0, fib(0)) assert_equal(1, fib(1))これならOK。
テストのところを今のうちに綺麗にするために配列にしておこう。require './assert_equal' def fib(n) if n==0 return 0 end if n==1 return 1 end end [[0,0],[1,1]].each do |index, expected| assert_equal(expected), fib(index)) end第2項以降
フィボナッチ数列の第2項は第0項+第1項。この辺からfib(n) = fib(n-1)+fib(n-2)が使えるぞ!
講義ではTDDの体験のために遠回りしたけどこの業界の人ならここまでジャンプできるでしょう。
if文のところを綺麗にします!def fib(n) return 0 if n==0 return 1 if n==1 endこうしてから実装に進む。テストも追加。
require './assert_equal' def fib(n) return 0 if n==0 return 1 if n==1 return fib(n-1) + fib(n-2) end [[0,0], [1,1], [2,1]].each do |index, expected| assert_equal(expected), fib(index)) endいい感じ。return文が3つあって気持ち悪いけど、n==0でもn==1でもなかったら3つ目のreturnが実行されるのでこれでOK。
expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal.完璧やーん。もっとテスト追加。
[ [0,0], [1,1], [2,1], [3,2], [4,3], [5,5], [6,8], [7,13], [8,21] ].each do |index, expected| assert_equal(expected, fib(index))これにして、実行!
$ ruby fobonacci.rb +[main] expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal. expected :: 2 result :: 2 succeeded in assert_equal. expected :: 3 result :: 3 succeeded in assert_equal. expected :: 5 result :: 5 succeeded in assert_equal. expected :: 8 result :: 8 succeeded in assert_equal. expected :: 13 result :: 13 succeeded in assert_equal. expected :: 21 result :: 21 succeeded in assert_equal. expected :: 34 result :: 34 succeeded in assert_equal.完璧だし、簡単!!以上!!
- source ~/Library/Mobile Documents/com~apple~CloudDocs/KG/class/M1/multi_scale_sim/grad_members_20f/members/ryomichi56/./qiita/no10_1.org
- 投稿日:2020-11-30T23:04:47+09:00
ActiveRecord inverse_ofの使い所
Rubocopの違反(RuboCop::Cop::Rails::InverseOf)が発生したので、inverse_ofについて調べてみました。
普通の関連付けではinverse_ofを使用しなくても、自動的に追えるようになっているので特に設定は必要ありません。
model.rbclass Parent < ApplicationRecord has_many :children end class Child < ApplicationRecord belongs_to :parent endしかし、関連付けでscopeをつける場合はinverse_ofを使用しなければいけません。以下のようにinverse_ofを設定してあげると逆関連づけを指定できます。
model.rbclass Parent < ApplicationRecord has_many :children -> { order(:height) }, inverse_of: :parent end class Child < ApplicationRecord belongs_to :parent, inverse_of: :children end参考にした記事のurl
Railsガイド inverse_of
https://railsguides.jp/association_basics.html#belongs-to%E3%81%AE%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3-inverse-of
- 投稿日:2020-11-30T22:53:50+09:00
ActionMailerのSMTP設定を動的に変更する
この記事について
Rails からメールを送る際、ActionMailerを使ってメールを送るケースが多いと思だろう。
しかし メールを送るサーバーを動的に設定したい場合はどうすればいいかについて解説している記事は少ないため、この記事で解説する。一般的にRailsからActionMailerを使ってSMTP経由でメールを送る場合、下記の記事が参考になる。
この場合、SMTPサーバーの設定を
config/environment.rb
やconfig/environments/production.rb
にconfig.action_mailer.smtp_settings = { ... }
として設定することになる。これは、1つのアプリケーションから1つのメールサービスしか使用しない場合は問題なく動作するが、ユーザーやグループによってアプリケーションが使用するメールサーバーを変えたい場合は意図したように機能しないだろう。
この記事ではユーザーやグループによってアプリケーションが使用するメールサーバーを変えたい場合、つまりは1つのアプリケーションから複数のメールサーバーを使用する場合について1つの解法を示していく。
定石
Railsでメールを送る場合、Railsガイド / Action Mailer の基礎 / Action Mailerを設定する に沿ってメールサーバーの設定を
config/environment.rb
やconfig/environments/production.rb
に対してconfig.action_mailer.smtp_settings = { ... }
として設定することになる。config/environment.rbActionMailer::Base.smtp_settings = { :user_name => 'your_sendgrid_username', :password => 'your_sendgrid_password', :domain => 'yourdomain.com', :address => 'smtp.sendgrid.net', :port => 587, :authentication => :plain, :enable_starttls_auto => true }この場合はActionMailer経由の全てのメールがこのSMTP設定を用いて配信されることになる。
カスタマイズ
しかし実際のところはユーザーやグループによっては特定のメールサーバーにSMTPで接続してメールの配信を行いたいといったケースが出てくる事が多い。
上記のように
ActionMailer::Base.smtp_settings = {}
で設定してしまう場合、適用した瞬間から次に上書きされるまでの間はそのSMTP接続を使用してメール送信を行なってしまうため、タイミング次第では意図しないSMTPサーバーの使用・・・古い言葉を使うと『混線』を起こすことになる。これに対する1つの解法としては、ユーザーやグループといったメールサーバー毎にコンテナ化したアプリを配置することで解決する方法もあるが、今回は1つのRailsアプリ(コンテナ)で複数のメールサーバー話を使用するカスタマイズを行うやり方の1つを紹介する。
やり方
カスタマイズといってもそう大したことをするわけではなく、
ActionMailer::Base#mail
の引数であるdelivery_method_options:
を利用する。
delivery_method_options
については Railsガイドで解説されているが、実際に認知されているケースは多くないように感じる。Railsガイドでは
user_name
、password
、address
を上書きしている例が書かれているが、実はこのdelivery_method_options:
は同様に他のsmtp_settings
の値についても設定する事ができる実際にやってみる
はじめに、
ActionMailer::Base
モジュールに設定されたデフォルトのsmtp_settings
を取得してみるActionMailer::Base.smtp_settings=> {:address=>"localhost", :port=>25, :domain=>"localhost.localdomain", :user_name=>nil, :password=>nil, :authentication=>nil, :enable_starttls_auto=>true}何も設定されない場合は上記のような設定になっている。
ここでSaaS経由でのメール送信について実行してみる。
SendGridでAPIキーを使ったメール送信を行う場合、SMTP接続設定パラメータは下記のようになる。
ActionMailerの設定項目 設定値 user_name
apikey
password
APIキーの値 (仮に {APIキー}
とする)address
smtp.sendgrid.net
domain
メール送信元ドメイン (仮に {送信元ドメイン}
とする)authentication
login
enable_starttls_auto
true
port
587
これをActonMailerで動的に使用する場合、下記のように
delivery_method_options:
を使って、メール毎のSMTPサーバーの設定を上書きする。
(送信先アドレスは、仮に{YOUR_TEST@MAIL.ADDRESS}
として設定)ActionMailer::Base.mail( to: '{YOUR_TEST@MAIL.ADDRESS}', from: 'from@{送信元ドメイン}', subject: 'テストメール', body: 'メール本文', delivery_method_options: { user_name: 'apikey', password: '{APIキー}', address: 'smtp.sendgrid.net', domain: '{送信元ドメイン}', authentication: 'login', enable_starttls_auto: true, port: 587, } ).deliver_later上記の例では
ActionMailer::Base
に対して上書きを行っているが、app/mailers
配下の各クラスに対しても同様の処理を行ってメール配信を行う事ができる。ex)HogeNotifyが存在している場合HogeNotify.mail( to: '{YOUR_TEST@MAIL.ADDRESS}', from: 'from@{送信元ドメイン}', subject: 'テストメール', body: 'メール本文', delivery_method_options: { user_name: 'apikey', password: '{APIキー}', address: 'smtp.sendgrid.net', domain: '{送信元ドメイン}', authentication: 'login', enable_starttls_auto: true, port: 587, } ).deliver_laterまた、rails consoleから確認する場合は
deliver_later
ではなくdeliver
を使う事で同期的にメールを送って確認する事ができる。1. consoleを起動する
bundle exec rails c
Running via Spring preloader in process 2509 Loading development environment (Rails 6.0.3.4)2. メールを送信する
ActionMailer::Base.mail( to: '{YOUR_TEST@MAIL.ADDRESS}', from: 'from@{送信元ドメイン}', subject: 'テストメール', body: 'メール本文', delivery_method_options: { user_name: 'apikey', password: '{APIキー}', address: 'smtp.sendgrid.net', domain: '{送信元ドメイン}', authentication: 'login', enable_starttls_auto: true, port: 587, } ).deliverまとめ
以上のように ActionMailerが利用するメールサーバーは、
config/environment.rb
やconfig/environments/production.rb
に対して設定する以外に、ActionMailer::Base#mail
の引数であるdelivery_method_options:
を使って設定する事で、動的なSMTPサーバー設定を施す事ができる。これはサービスを利用するユーザーやグループ単位でのメールサーバの切替等に活用できる仕組みであり、Railsの高い汎用性を表している一面であるとも言えるのではないだろうか。
- 投稿日:2020-11-30T22:33:29+09:00
Rubyのアンインストール方法
https://qiita.com/Okame-chan/items/39052dc4d4c3cebfb1ee
こちらの記事を参考にさせていただきました。
実行したこと
$ ruby -vインストールされてる、Rubyのバージョンを調べる。
$ which rubyRubyの場所を確認すると、 ~/.rbenv/shims/ruby
rbenvにありますよ、となっていたので$ rbenv uninstall 【Rubyのバージョン】とすることで、無事アンインストールできました。
- 投稿日:2020-11-30T21:41:03+09:00
image_tag
railsチュートリアルを学習している時
問 image_tagで画像を表示してください
まずimege_tagってなんぞやということで検索。
image_tagとはHTMLの
タグを生成するためのメゾット
らしい。
なるほど、、img以外にも画像を挿入する方法があるのか
書き方
image_tag "rails_icon.png", alt: "Rails icon", id: "pic1", class: "image"
app/assets/images配下に画像がある場合これで良いらしいが、
public配下の画像を表示する場合には、画像ファイルのパスを次のように / から記載する必要があるらしい。
image_tag "/rails_icon.png", alt: "Rails icon", id: "pic1", class: "image"
なるほど。。。
- 投稿日:2020-11-30T18:41:19+09:00
Rails パンくずリストの作成
はじめに
Railsアプリのヘッダー部分にパンくずリストを追加しました。忘れないように書き記します。
開発環境
ruby 2.6.5
Rails 6.0.3.4目次
1.Gemの導入
2.パンくずの設定
3.CSSの設定1.Gemの導入
gretelというGemを使用する。 下記Gemfileに追記後、ターミナルで忘れずにbundle installを実行する。
Gemfilegem "gretel"2.パンくずの設定
パンくずの設定を書き込むbreadcrumbs.rbファイルを作成する。作成方法は下記のようにターミナルでコマンドを実行する。
ターミナルrails g gretel:install今回下記のような4層でパンくずリストを構成する。
トップページ > 掃除提案 > 登録一覧 > 掃除箇所の登録config/breadcrumbs.rbcrumb :root do link "トップページ", root_path end crumb :clean_suggestions do #ページの名前 link "掃除提案", clean_suggestions_path #リンク名、リンク先ページ parent :root end crumb :suggestions do link "登録一覧", suggestions_path parent :clean_suggestions end crumb :new_suggestion do link "掃除箇所の登録", new_suggestion_path parent :suggestions end各ヘッダーのビューにパンくずリストを追記する。なお「separator: " > "」はリスト間に「>」を挿入する。これによりブラウザ上に表示される。
トップページのヘッダー.html.erb<%= link_to "トップページ", root_path, class: :logo %> <% breadcrumb :root %>掃除提案のヘッダー.html.erb<% breadcrumb :clean_suggestions %> <%= breadcrumbs separator: " > " , class: :logo %>登録一覧のヘッダー.html.erb<% breadcrumb :suggestions %> <%= breadcrumbs separator: " > " , class: :logo %>掃除箇所の登録のヘッダー<% breadcrumb :new_suggestion %> <%= breadcrumbs separator: " > " , class: :logo %>3.CSSの設定
logoクラスは「>」に適用される。現在のページを表す部分は自動的にcurrentクラスが割り当てられている。下記記述により、現在のページを太字とし、それ以外にカーソルを合わせると色が変わるようになる。
header.css.logo { margin-left: 3vw; } .logo a { margin-right: 0.5vw; } .current { font-weight: bold; margin-right: 1vw; } .logo:hover,.logo a:hover { color: Chocolate; }以上
- 投稿日:2020-11-30T18:32:53+09:00
RubyとPythonの言語の超簡易的比較
RubyとPythonの比較
Ruby(Rails)の学習も一通り終わり、次の学習言語としてPythonを学んでいこうと思う.
ただ、Pythonとは何か?
どちらも可読性が高いのは知っているが、具体的な違いを持って調べてみた。Ruby
1.Rubyは日本人が開発した言語で日本語の文献が多いので比較的、日本人が学習しやすい。
2.Webアプリケーション開発で主に使用される言語(例:twitter)
3.Ruby on RailsなどのすぐにWebアプリケーション(サイト等)を作成するためのフレームワークがあるのでベンチャー企業などに使われることが多い。Python
1.シンプルで覚えることが少ない構文。他の言語と比べて短く簡単にコードが書ける(Rubyとどのぐらい差があるかは学習して感じていく)
2.Webアプリケーションにも扱われることもあるが、真の実力を発揮する分野としては機械学習とAI開発にある
3.例として機械学習では大量のデータ(ビックデータ)から解析や計算をすることができるので、マーケティングに使われることもある。(YouTube)Pythonの学習の進め方(お金を掛けたくない自己流独学の予定)
1.Progateで基礎中の基礎を学ぶ
2.paizaで動画の閲覧(ドットインストールでも可)
3.図書館から書籍を借り、コードを記述しながら学習(どういうアプリを作成するか考えながら)
4.アイディアを浮かべたものをオリジナルアプリとして形にする(AWSアカウントは別のものでもう使っているのでherokuへデプロイ予定)
- 投稿日:2020-11-30T18:16:14+09:00
rakeの使い方
make, antのruby版
rakeはmakeやantのruby版です.いくつかのコマンドを実行する際に役に立ちます.典型的な例は,
task :default do system 'rake -T' exit end desc 'hello NAME' task :hello do name = ARGV[1] puts "Hello #{name}!" exit endこれをRakefileに書き込み,以下のように実行します.
> rakeRakefileが用意しているtask(仕事)が表示されます.
今書いた,Rakefileの中身を見ていきましょう.
- descの後にはrake -Tとした時の説明文
- :default はrakeが引数なしで呼ばれた時の動作,
- それ以外はoptionで呼ばれるtaskの名前
- taskの中には標準のruby言語で,動作を記述
':'で始まる変数はsymbolと呼ばれるクラスで,名前の代わりをしてくれます.
rakeはDSL(Domain Specific Language),その場に特有の言語を作っちゃおうという発想です.したがって純正のruby言語ではありませんが,ちょっとした仕事(task)を使いやすいように拡張されています.
system call
一番Rakefileに記述することの多い関数はsystemです.これはsystemコマンドを起動する関数です.それは,手でやる作業をそのまま記述するからです.つまり,忘れそうなことはうまくメモしておくんです.例えば,Rakefileに
desc 'git pull' task :pull do p comm = "git pull origin main" system comm exit endとRakefileに書き込み,以下のように実行します.
> rake pullすると, git pull が実行できます.
さらに,githubの共有をするためのコマンドも同じように.
desc 'git push' task :push do p comm = "git add -A" system comm p comm = "git commit -m \'hoge\'" system comm p comm = "git pull origin main" system comm p comm = "git push origin main" system comm exit end> rake pull $[point] p commで命令(command)が何かをpしておくこと
- source ~/Desktop/grad_members_20f/members/mm-cell/post_org/rake.org
- 投稿日:2020-11-30T17:30:35+09:00
Float型にて、計算した際に、値に少々ズレが生じる件について
環境
Ruby 2.6
Rails 5.1.7背景
機能実装中、数値を計算する処理が何か合わないなぁと思ったら表題の現象が起きてた。
これは初めて遭遇したので備忘録として。現象
rubyirb(main):005:0> 2.2 * 100 => 220.00000000000003 irb(main):006:0> 2.3 * 100 => 229.99999999999997 irb(main):007:0> 2.4 * 100 => 240.0Float型に100掛けると何故か100倍になっておらず少々の誤差があることに気づいた
対応
https://qiita.com/yusabana/items/fd4a0185c1f120403a74
こちらの記事を参考にBigDecimalを使用してあげると綺麗な数値が出るrubyirb(main):017:0> (BigDecimal(2.2.to_s) * 100).to_f => 220.0 irb(main):015:0> (BigDecimal(2.3.to_s) * 100).to_f => 230.0 irb(main):018:0> (BigDecimal(2.4.to_s) * 100).to_f => 240.0以上
- 投稿日:2020-11-30T17:24:15+09:00
shell + emacsの基礎
shell[I] command基本
shell(殻)ってのは,operating systemの中心(kernel: 核)の外側にあって,keyboardの入力を受け取って,kernelへ渡して,スクリーンへいい感じで出力するという機能を受け持ちます.shellにはいくつもの派生があります.ubuntuとかはbashをdefaultで使っていますが,fish, zshってのが今の流行です.
shellに命令(command)を投げてやり取りするため,command line interface(cli)やcharacter user interface(cui)と呼ばれます.
commandは
command [objects]
あるいは
command [options] [ojbects]
というのが基本形です.[]は省略可能を意味します.optionsは
-
記号の後ろに文字(short option)で打つか,--
の後ろにフル記述(long option)で打つかの2種類があります.
man man
を確かめてください.manのmanualが表示されます.NAME, SYNOPISI, OPTIONなんかが表示されます.終わるのはq(uit)です.
shell[II] directory,file関連
まずはdirectory(フォルダーといった方がわかりやすいかも)関連の命令です.ファイルを整理するための電話帳(directory)といった意図です.
Fig. ディレクトリー構造と絶対パス,相対パス.
mkdir ディレクトリ名 ディレクトリ作成 touch ファイル名 ファイル作成 pwd 絶対パスの表示 cd ディレクトリ名 ディレクトリ変更 cd .. 直前にいたディレクトリへ移動 ls ディレクトリ内のファイル一覧 cp コピー元 コピー先 ファイルなどコピーする rm ファイル(ディレクトリ)名 削除する mv 移動元 移動先 ファイル等の移動,名前変更 etc…
emacs
emacsは高性能なeditorの一つです.
一連の流れを記すと,
- emacs REDAME.org
- なんかの編集操作
- c-x c-s (save)
- c-x c-c (quit) or c-z(stop)
(quit:編集終了.stop:一時中断.fgで再開できる.)よく使う操作.
- c-p, n, b, f, a, e # 移動
- c-d, k # 削除
Fig. emacs key bindチートシート; keybind文字には,命令の意味があります. shell[III] process関連
process関連の操作として用意されているコマンドは
- ps, top # process status,
- fg, bg # fore, back ground
- kill -9 PID # process id
なんかです.
emacs でc-zでstopしてbashに戻ってきても,psあるいはtopするとemacsが動いていることが確認できます.これは,emacsがbgにいて,fgすると操作がbashからemacsに渡されることを意味します.emacsを使っていて,気づかぬ間にたくさんのemacsが立ち上がってしまっていることがあります.そうすると,折角の編集結果が失われることがあります.気がついたらkill でそのprocessを消すようにしてください.
git
gitはLinuxの生みの親のLinus Torvalsが開発したバックアップソフトです.情報共有にも使え,その統合サービスを提供しているのがgithubです.最初に必要な設定は以下のとおりです.
git config --global core.editor emacs
# vi とかcodeでもOKgit config --global user.name "FIRST_NAME LAST_NAME"
git config --global user.email "MY_NAME@example.com"
githubにあるrepositoryをlocalに移すには,
- git clone GITHUB_REPOSITORY
- cd REPOSITORY
- git remote -v
とします.
Fig. gitコマンドによるバックアップ.ここでは赤枠の中だけを利用. 基本の作業は
- git pull origin main
- 編集
- githubに掲載
- git add -A
- git commit -m 'first commit' # messageをつける,あるいは-m以降を省略してeditorへ.
- git pull origin main # 他の人がpushして最新になってない可能性が高いので..
- git push origin main # 自分のをpush. ここでもたつくとhintが出るので,再度pull
- source ~/Desktop/grad_members_20f/members/mm-cell/post_org/shell_emacs.org
- 投稿日:2020-11-30T15:12:59+09:00
Railsでflatpickrを使ってみる
はじめに
フォームから日付を入力する際、カレンダーから直感的に日付選択できるようにする"datetimepicker"等の日付ピッカー。
その一種であるflatpickrをRailsで使う方法がQiitaに見当たらなかったので記事にしてみました。
なお、当方初学者かつ初投稿なので、間違いなどございましたらご指摘いただけますと幸いです。環境
- ruby 2.6.6
- Rails 5.2.4.4
flatpickrについて
flatpickrは非常に軽量で導入も簡単です。
flatpickr以外の日付ピッカーとしてbootstrap-datetimepickerが有名ですが、bootstrapやjQueryに依存していたり、bootstrapのバージョンの互換性などなにかと面倒です。
私のような初学者でもポートフォリオへの導入がしやすいかと思います。関連ページ
- introduction
こちらが公式サイトです。(英語サイト)- flatpickrドキュメント翻訳
公式サイトを日本語化してくださっているサイトです。flatpickrは色々細かく設定できるようなので、上記サイトを御覧ください。
- flatpickr-rails (github)
Railsで簡単に使えるようgemパッケージ化してくれています。
今回はこちらを使って導入していきます。flatpickrインストール
今回は先程のGemを使用するので、Gemfileに以下を記述し、インストールします。
gemfilegem 'flatpickr'tarminal$ bundle install
app/assets/stylesheets/application.css
の拡張子cssをscssに変更
上部にflatpickrを読み込ませる記述を追加します。application.scss/* ... ... // 〜〜〜〜 以下を追加 〜〜〜〜 *= require flatpickr // 〜〜〜〜 以上を追加 〜〜〜〜 */
app/assets/javascripts/application.js
も同様に記述します。
日本語化するのであれば、一緒にflatpickr/l10n/ja
も導入しましょう。application.js//= require rails-ujs //= require activestorage // 〜〜〜〜 以下を追加 〜〜〜〜 //= require flatpickr //= require flatpickr/l10n/ja // 〜〜〜〜 以上を追加(require turbolinksより上に追加) 〜〜〜〜 //= require turbolinks //= require_tree以上でflatpickrの準備は整いました。次は、viewでフォームから実際にflatpickrを表示してみましょう。
表示してみる
今回はnewページで、Taskモデルのdate型のaction_atというカラムにデータを入れる場合を想定しましょう。
モデルやカラム名は適宜読み替えて実装してください。viewではRailsのいつもの感じで
form_with
を使ってフォームを作りましょう。views/tasks/new.html.erb<%= form_with(model: @task, local: true) do |f| %> <%= f.text_field :action_at, id: "flatpickr", type: "text", readonly: "" %> <% end %>
text_field
にわかりやすくid: "flatpickr"
と記述しました。
idの名前は何でもいいですが、次のjsに書くflatpickrの第一因数と一致させるようにしてください。
また、readonly:""
でユーザーにflatpickr以外から文字入力をさせないようにしましょう。続いてJavaScriptの設定に移ります。
新しいjsファイルを作成する場合、ファイル名をflatpickr.js
にすると//= require flatpickr
と被って動かなくなるので注意しましょう。
turbolinksを使用していない場合は最初の行は必要ありません。datetime.jsdocument.addEventListener('turbolinks:load', () => { flatpickr('#flatpickr') })これでフォームをクリックするとflatpickrが表示されるはずです!
カスタマイズ例
jsでのカスタマイズ例なんかは既にいろいろ記事が上がっていたり、公式サイトにも載っているのですが、少しだけ例を挙げておきます。
日本語化とスマホ対応
datetime.jsdocument.addEventListener('turbolinks:load', () => { // カレンダーの日本語化 flatpickr.localize(flatpickr.l10ns.ja) // カレンダー表示 flatpickr('#flatpickr', { // スマートフォンでもカレンダーに「flatpickr」を使用する設定 disableMobile: true, }); })
//= require flatpickr/l10n/ja
で日本語化を読み込んでいるので、これで曜日などが日本語になります。
選択可能日を設定
datetime.jsdocument.addEventListener('turbolinks:load', () => { const TODAY = new Date(new Date().setHours(0, 0, 0, 0)) flatpickr.localize(flatpickr.l10ns.ja) flatpickr('#flatpickr', { disableMobile: true, //今日までを選択可能にする maxDate: TODAY }); })今日までを選択可能にしました。
minDate:
とかで一ヶ月前までを選択可能にしたりもできます。
11月28日時点なら、29日、30日と来月以降の文字は選択不可になっています。テーマ変更
application.scss/* ... ... *= require flatpickr *= require flatpickr/themes/dark.css */
flatpickrには色々なテーマが用意されており、scssに読み込ませるだけで変更できます。
公式サイト日本語約ページにサンプルがあります。
Themes
上の例はdarkテーマを採用していますが、darkのところを他のテーマ名に変えるだけで適用できます。
material_blue.css
airbnb
- 投稿日:2020-11-30T14:12:40+09:00
[Rails]ページネーション機能
実装したいこと
投稿が多くなってくると一覧表示した時に見にくくなってしまうのでページを分けました。
目次
- 1. kaminariのインストール
- 2. ページネーションの表示
- 3. デザイン
- 4. ラベルの変更
1. kaminariのインストール
Gemfileの一番下に以下を記述し、ターミナルでbundle installを実行します。
Gemfilegem 'kaminari'2. ページネーションの表示
今回はbefore_actionを用いて投稿一覧を表示しています。
ページネーションを表示させたいデータに.page(params[:page])を追記します。
また、.per(10)を追記することで1ページに10件のデータを表示するという設定をします。
デフォルトでは25件が表示されるようになっています。app/controllers/posts_controller.rbdef index_post @posts = Post.order(created_at: :desc).page(params[:page]).per(10) endページネーションを表示させたいところに<%= paginate @posts %>を追記します。
app/views/posts/index.html.erb~略~ <div class='item-contents'> <h2 class='title'>クチコミ一覧</h2> <%= render "shared/posts" %> <%= paginate @posts %> # 追記 </div> </div>3. デザイン
今回はbootstrapとFont Awesomeを用いて実装しました。
まずbootstrapとFont Awesomeを読み込みます。app/views/layouts/application.html.erb<!DOCTYPE html> <html> <head> <title>CosmeticReview</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> # 以下を追記 Font Awesome読み込み <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.9.0/css/all.css"> # 以下を追記 bootstrap読み込み <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%# <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <%= yield %> </body> </html>次に、kaminariにbootstrapを適用させます。
ターミナルで以下を実行します。ターミナル
rails g kaminari:views bootstrap3実行後、app/views/kaminariフォルダが自動生成され、ページネーションにbootstrapが適用されます。
CSSでさらに自分の好みのデザインに変更します。
app/assets/stylesheets/index.css/* ページネーション */ .pagination { display: flex; justify-content: center; } .pagination > li > a { border: none; color: #999; } .pagination > li > a:hover { color: turquoise; background-color: white; } .pagination > .active > a { color: turquoise; background-color: white; } .pagination > .active > a:hover { background-color: white; color: turquoise; } /* --ページネーション */4. ラベルの変更
今回はラベルにアイコンを用いて実装しました。
config/locales/ja.ymlja: views: pagination: first: <i class="fas fa-angle-double-left"></i> last: <i class="fas fa-angle-double-right"></i> previous: <i class="fas fa-angle-left"></i> next: <i class="fas fa-angle-right"></i> truncate: "..."3 参考リンク
https://github.com/kaminari/kaminari
https://qiita.com/rio_threehouse/items/313824b90a31268b0074
- 投稿日:2020-11-30T14:10:17+09:00
Ruby on Rails モデル検証〜文字列長の検証を追加〜
モデルの検証に文字列長の検証を追加
データベースの定義でnameカラムの文字列を30文字以下に制御しているが
app/models/task.rbclass Task < ApplicationRecord validates :name, presence: true endこのままだと、30文字を超える文字列を超える文字列が入力された場合、登録や更新の際に例外が発生してしまう。
これではユーザーが問題の原因に気づきづらく、動線も不便になってしまうので、30文字を超える入力の時に
わかりやすい検証エラーが表示されるようにしたいと思います。まずTaskモデル(app/models/task.rb)にコードを追加します。
app/models/task.rbvalidates :name, length: { maximum: 30 }これで30文字を超えるとエラーメッセージが返ってきます。
文字数制限を加えたい場合は参考にしてみてください。
- 投稿日:2020-11-30T13:40:05+09:00
messaging apiで勤怠管理botを作った。
はじめに
実家の会社ためにLINEのMessaging APIを使って勤怠管理botを作りました。
なぜ作ったか
- 最初は給与計算アプリを作ろうと思ったが、勤怠記録の情報がないとそもそも計算できないと気づいた。
- 実家の会社では祖母が手動で給与計算をしているが、最近計算間違いが多くなった。
- LINEのMessaging APIであれば、誰でも簡単に使用できると思った。
- 作成期間:約2週間
開発環境
- 開発言語
- Ruby
- フレームワーク
- Ruby on Rails
- データベース
- sqlite3
- 使用技術等
- Linter
- rubocop
- Ngrok
- Messaging API
基本機能
ユーザーごとの出勤・退勤時間の登録
ユーザーごとにその日の出勤時間・退勤時間を登録できます。
既にその日の出勤時間を登録してる場合と、出勤時間を登録せずに退勤時間しようとしても登録できないようにしています。
今日の勤務記録の修正
勤務記録はその日の記録のみ修正可能です。
出勤時間が登録されていない場合は修正は不可能にしています。
今日・今月・先月の勤務記録の参照
勤務記録は今日・今月・先月の記録が参照可能です。
記録がない場合は記録なしと表示します。
検討している追加機能・改善点
- 退勤時間の登録し忘れ防止機能(時間指定メッセージでいけると思う)
- 早出や残業などの区別(実家の会社ではよほどのことがない限りいらないかも)
作った感想
Messaging APIを触るのは初めてだったが、思ったよりも簡単な記述で幅広い機能の実装が可能ということがわかった。
LINEが非常に一般的なツールなので、ユーザーの敷居も低く、ユーザーフレンドリーなbotを簡単に作れる点は非常に素晴らしいものだと感じた。今後について
今回は、最初は給与計算アプリを作ろうと思ったが、勤怠管理が必要ということで勤怠管理botの作成に至った。今後はこのbotで集めた記録を元に給与計算を作ろうと思っている。
- 投稿日:2020-11-30T12:49:51+09:00
疎通確認が目的のタスク名には ping を入れるとわかりやすい
こんにちは、株式会社ベストティーチャーで元気に働く たわら です。業務駆け出しエンジニアです。
業務に駆け出すと、いろんな学びがあります。今回はpingです。
とある日
先輩 「hogeサーバーから毎日何らかのデータを取ってくるrakeタスクを作ってほしい」 先輩 「諸事情で、通信すること自体が目的なんだ」 ボク 「ハイ!」何とか実装して、タスク名を
request_to_hoge
としてプルリクを出すと、、、先輩 「、、、何をリクエストしてるかわかりずらいですね、、、」 先輩 「後から参画するエンジニアにもわかりやすい名前にしよう」 先輩 「こういうときは ping を変数に入れるといいよ」ping って??
対象のコンピューターときちんとつながっているかどうか、を確認するときに使用するコマンドのことです。
例えば、
Raspberry Pi
にUbuntu
を入れて、ネットワークを設定して、ホストマシン(Mac)側からssh接続するための前準備として、まず通信接続を確認するときなどに当該IPアドレスを指定して、ping
コマンドを利用します。この作業を疎通確認、と言います。
なので、変数に
ping
を入れると疎通確認を目的としたタスクだ、ということが示せます。先輩 「ということで、ping_hoge という名前にしよう」 先輩 「これなら後から参画したエンジニアもタスクの意味が把握しやすいからね」 ボク 「ハイ!」最後に
後から参画する方にわかりやすい名前をつける、という気づきがありました。
変数がわかりにくいとコールドリーディングにコストがかかってしまいます。
この瞬間だけではなくて、長い時間のなかでわかりやすい変数の名前をつけるのが大事なのですね。参考文献
用語集「pingとは?」
https://www.cman.jp/network/term/ping/pingとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word124.htmlpingを知ろう - Qiita
https://qiita.com/masapiko/items/57d6d6f666ee0412383b
- 投稿日:2020-11-30T12:25:19+09:00
1-nの関連モデルでnのデータを取得する場合は1のモデルから取ろうという話
前提
※Railsでの話ですが、他のライブラリにも同じことが言えると思います
以下のモデルがあります
User
UserPost
※1-nの関係以下のURLがあります
/posts # 自分の投稿一覧を取得 /users/:user_id/posts # user_idの投稿一覧を取得Controllerの処理
/postsの例
UserPost.where(user_id: @current_user.id)....こんな感じでやったりする人がいますが、これはだめです。
こうしましょう@current_user.user_posts...UserPostからとるようにすると、なんかの手違いでwhere条件を消してしまったりして、userの条件が外れる可能性があります。
userからとるようにしておけば、必ずそのユーザーで絞り込まれるので、その事故を防ぐことができます/users/:user_id/postsの例も理由は同じです
結論
必ず親側のモデルからデータをとるようにするクセをつけるといいと思います
- 投稿日:2020-11-30T12:18:46+09:00
Ruby on Rails ビューで検証エラーに対応する
ビューで検証エラーに対応する
登録画面のフォーム部分が次のようになっている場合
app/views/tasks/_form.html.slim= form_with model: task, local: true do |f| .form-group = f.label :name = f.text_field :name, class: 'form-control', id: 'task_name' .form-group = f.label :description = f.text_area :description, rows: 5, class: 'form-control', id: 'task_description' = f.submit nil, class: 'btn btn-primary'ここにはまだ検証エラーメッセージを表示する部分がない。
form_withの上に、エラーメッセージを表示するための領域を作りたいので次のように編集。app/views/tasks/_form.html.slim- if task.errors.present? ul#error_explanation - task.errors.full_messages.each do |message| li = message = form_with ...上記のコードは、errors_present?を使って検証エラーの有無を調べエラーがある時にエラーメッセージを表示するようにしている。
- 投稿日:2020-11-30T11:57:19+09:00
RubyとPythonの構文比較まとめ
はじめに
ひとつのプログラミング言語を学ぶと、他のプログラミング言語にも応用できると言われています。
そこで、言語の壁を超えて、基本的な構文を比較しながらまとめてみました。投稿者のスキルセット
・RailsでWebアプリケーションを作成したことがある
・ProgateやRailsチュートリアルで、Rubyを学んだ経験がある
・ProgateでPythonを学習中対象者
・Rubyを学んでいて、Pythonに興味を持っている方
・逆にPythonを学んでいて、Rubyにも興味を持っている方環境
・MacOS Catalina 10.15.7
・Ruby 2.7.1
・Python 3.8.6構文
「Hello, World!」を出力する
hello.rbputs 'Hello,world!'hello.pyprint('Hello, World!')putsとprintで言語の違いがありますが、おおむね同じですね。
コメント
comment.rb# これはコメントです
comment.py# これはコメントです
コメントの付けかたは、『#』で変わりません。
条件文
if.rbdef check(number): if number % 4 == 0: print('number is divisible by 4') elsif number % 3 == 0: print('number is divisible by 3') elsif number % 2 == 0: print('number is divisible by 2') else: print('number is not divisible by 4, 3, or 2')if.pydef check(number): if number % 4 == 0: print('number is divisible by 4') elif number % 3 == 0: print('number is divisible by 3') elif number % 2 == 0: print('number is divisible by 2') else: print('number is not divisible by 4, 3, or 2')Rubyでは『elsif』ですが、Pythonでは『elif』なところに注意が必要です。
おわりに
今回は、分かりやすい一例をご紹介しました。
基本的には、一つの言語を学べば、他の言語にも活かせると言えそうです。
まずは基礎となる言語の理解をしっかりと深めるところから始めましょう!参考
・ゼロから学ぶ Python
https://rinatz.github.io/python-book/
- 投稿日:2020-11-30T07:18:11+09:00
RailsにおけるRESTfulな設計とはなにか?
RESTfulとは
RESTful APIは、基本的に「RESTの原則」に従って実装されているWebシステムのHTTPでの呼び出しインターフェースのことを指します。
なるほど..わからん。
Railsの根本的なところやん?こんなに理解がぼんやりしていてええの?
ってことでこの曇った視界をはっきりさせていく。RESTful
アプリケーションを構成するリソースをHTTPリクエスト(GET/POST/PUT/DELETE)で作成、読み出し、更新、削除できる仕組み
要するにURLに対してどのHTTPリクエストを送るかでそのあとの動作をより分けているイメージか。
アプリケーションでユーザー関連のもろもろを取り扱うUserリソースを例にしてみる
アプリケーションの下記のような動作があったとする。
- ユーザーを新しく登録するページを表示(new)
- ユーザーを新しく作る(create)
- 一人のユーザーを閲覧する(show)
- 登録ユーザーの一覧をみる(index)
- ユーザー情報を更新するページを表示(edit)
- ユーザー情報を更新する(update)
- ユーザーを消す(destroy)
これを冒頭でも述べた動作で振り分ける
ユーザーを新しく作るなら
HTTPリクエストは POST
URLは/users
こうするとcreateアクションを呼び出すことができる。
※Railsではindex, show, new, edit, create, update ,destroyが暗黙のリクエストRESTfulな設計を使うには
HTTPリクエスト、URL、アクションの設定はroutes.rbでできる。
post '/users', to: 'users#create'ただUsersリソースのように想定している動作がindex, show, new, edit, create, update ,destroyの7種類全てを使う場合はroutes.rbで
resources :usersの1行を追加するだけで全てのアクションが使える。
RESTfulな設計とは
・URLに対して、どのリクエスト(GET、POST、PUT、DELETE)かで結果が変わる仕組み
・routes.rbでその設定ができる。
・すべての挙動を想定している場合はresources :usersの一行でルーティング設定が終了する参考
https://wa3.i-3-i.info/word11405.html
https://qiita.com/kidach1/items/43e53811c12351915278
https://qiita.com/katsutakashima/items/47977b9e7d18cf816734
railsチュートリアル
Ruby on Rails 入門
- 投稿日:2020-11-30T03:19:02+09:00
Ruby オブジェクトってなんなの??に答える
adventカレンダー初日の担当をさせていただきます !
DMM WEBCAMPでメンターをしているtanidaです !Rubyのオブジェクトとは何か? オブジェクト指向とは何か?
そんな疑問に答えていければと思います。ではでは、オブジェクトの世界を覗いてみましょう!
そもそもRubyにおいてオブジェクトとは
オブジェクト(インスタンス)とは、あるクラスから生成されたデータのこと!
*オブジェクトとインスタンスは同じモノだと、とりあえず覚えてください。
オブジェクト指向って何なんですか?
プログラムはオブジェクト間のメッセージのやりとり
という考え方です。
この考え方を理解するためにも、オブジェクトについて理解を深めていきましょう。1章 実際にオブジェクトを作ってみる?
PCにRubyのインストールされてない方はこのサイトのEditorにソースコードを書いて試せます。
https://try.ruby-lang.org/Personクラス - 人クラス
object.rbというファイルを作成して以下のソースコードを実行してみます。
object.rbclass Person # initializeはオブジェクトの初期化のための特別なメソッド # クラス名.new()した時の引数が渡されます def initialize(name) @name = name end def greeting "Hi! I'm #{@name}!" end end # Personインスタンスを生成した後、initializeメソッドが呼び出されます。 # これがオブジェクト(インスタンス)です。 person = Person.new('menter taro') p person
#<Person:0x00007fbd8686d490 @name="menter taro">
がターミナル上で確認できました。2章 もう少しオブジェクト(インスタンス)について調べてみる?
1. 所属するクラス
インスタンスはクラスに所属しているので
class
メソッドを利用すると、オブジェクトが所属するクラスはどこか教えてくれます。puts person.class2. インスタンス変数
インスタンス変数とはインスタンスが保持している変数の事です。
先ほどのコードでいうと、@name
です。インスタンス変数は@マークがイニシャルでなければいけません。
インスタンス変数は同じインスタンス内であればその値を参照、変更ができます。
instance_variables
メソッドを利用するとインスタンス変数を教えてくれます。puts person.instance_variables3. インスタンスメソッド
インスタンスメソッドとは、クラス内に定義された、
クラスから生成されたオブジェクト(インスタンス)からしか呼び出せないメソッドのこと。puts person.class.instance_methods(false)instance_methodsの引数にfalseを付け加えると、
継承先のメソッドは表示しないようにしてくれます。(継承については説明を省きます)
今回はPersonクラスに定義されたインスタンスメソッドのみを聞きたいのでそうしています。Personクラスから生成されたオブジェクト(インスタンス)からならgreetingを呼べます。
puts person.greetingこの呼び方はできない
puts greeting3章 アクセスメソッドの利用?
attr_accessor (いわゆるgetter/setter)
attr_reader
(getter) とattr_writer
(setter) が融合したものオブジェクトの外部からインスタンス変数を直接参照したり、インスタンス変数の値を更新することはできません。
でも、オブジェクトの外部から、簡単にインスタンス変数の値にアクセスしたいし、更新もしたい。。。
しかし、アクセスメソッドなら実現できます。
attr_accessor
を追加するとオブジェクトから直接インスタンス変数の値を「参照」したり、「設定」したりできます。object.rbclass Person attr_accessor :name # インスタンス変数@nameの値の参照、設定が可能になる。 def initialize(name) @name = name end def greeting "Hi! I'm #{@name}" end end person = Person.new('menter taro') puts person.name # 参照 person.name = 'menter jiro' # 設定 puts person.name # 参照*ちなみに他のオブジェクト指向言語でも、getterとsetterというワード、概念はあります。
4章 重要な概念レシーバーとは?
メソッドの戻り値を受け取る対象のことです。
Personクラスにあるインスタンスメソッドgreetingを呼び出した時に
"Hi! I'm menter taro" といった文字列が戻り値となっていました。その戻り値を受け取る対象をレシーバーと言います.
先ほどのソースコードでの person がレシーバーとなります。puts person.greeting # "Hi! I'm menter taro" というメッセージをpersonが受け取る。つまり、レシーバーとはインスタンスメソッドを呼び出しているインスタンス自身のこと !
もう少しレシーバーについて詳しくみてきましょう。
呼び出されたメソッドのレシーバー自身を参照する - self
インスタンスメソッド内
でselfと記述すると、そのメソッドを呼び出したレシーバを取得できます。object.rbclass Person attr_accessor :name def initialize(name) @name = name end def greeting "Hi! I'm #{@name}" end def check_receiver # selfでレシーバーを取得 # 言い換えれば、インスタンスメソッドの呼び出し元のオブジェクトを取得する puts self # レシーバーのnameも取得 puts self.name end end person = Person.new('menter taro') person.check_receiverオブジェクト指向の世界では
「オブジェクトにセッメージを送り」 そして 「オブジェクトがメッセージを受け取る」
このように捉えられるのでレシーバーと呼ぶらしいです。オブジェクト指向プログラミングは
プログラムはオブジェクト間のメッセージのやりとり
、
`「オブジェクトのメッセージングによるプログラミングの手法」
と言われる理由が少しイメージできたのではないでしょうか?5章 クラスメソッドとは?
レシーバがインスタンスではなくクラスそのものであるメソッドの事です。
書き方は色々とあるのですがこの記事ではself.メソッド名
で定義します。
*先ほどのselfとは異なりインスタンスメソッド内
ではなくクラス内
に定義することになります。object.rbclass Person attr_accessor :name def initialize(name) @name = name end def greeting "Hi! I'm #{@name}" end # クラスメソッド def self.person_class_method "クラスメソッドの戻り値ですよ〜" end end person = Person.new('menter taro') puts Person.person_class_method # インスタンスからはクラスメソッドは呼び出せない puts person.person_class_methodじゃあ、クラスメソッドをどういう時に利用するの?
と言われると(まぁ好きなように使えるのですが)
インスタンスからメソッドを呼び出すと意味がちょっと違和感がある場合
や、
あるクラスのオブジェクトを参照中に他のクラスに関する処理を行いたい時
とかはクラスメソッドにすると良いかと思います。そのほうがソースコードの管理が楽になるはずです。例えば、5人分のPersonインスタンスを一括で生成したい時...
Personのインスタンスから直接呼ぶとチョット違和感ありませんか!...?
- いきなり真面目な顔で 「人間五人作れ」 という人がいたら太郎さんは困ります。
では実際にbulk_createというクラスメソッドで5人分のPersonインスタンスを生成してみます。
object.rbclass Person attr_accessor :name, :age def initialize(name, age) @name = name @age = age end def self.bulk_create(data) # mapでは各要素に処理を加えてその値を含んだ新しい配列を作ってくれています。 data.map { |d| Person.new(d[:name], d[:age]) } end end # Hashの配列を定義 data = [ {name: 'menter 一郎', age: 10}, {name: 'menter 二郎', age: 20}, {name: 'menter 三郎', age: 30}, {name: 'menter 四郎', age: 40}, {name: 'menter 五郎', age: 50} ] puts Person.bulk_create(data) puts p Person.bulk_create(data)
Person.bulk_create(data)
でクラスメソッドを呼び出すと、
五人のPersonオブジェクト(インスタンス)が格納された配列
が戻り値となっています。
その配列を受け取っているレシーバーはPersonクラス
ということです。という事で
クラスオブジェクトがレシーバーになる
メソッドがクラスメソッド
と言うことになります。なるほどぉ〜?? ん? チョット待って...
クラス「オブジェクト」
...?
オブジェクト
ってあるクラスから生成されたデータ
、インスタンス
の事って言ってましたよね...?
クラス
とオブジェクト
は別物なんでちゃんと「クラス」
って言った方がいいんじゃないんですか??うん、うん、そうそう... うん、オブジェクトはクラスに所属してるんだけどね...
まぁそうなんだけどね... 実はRubyでは「クラスもオブジェクト
」なんです... ( 'ω' )6章 クラスオブジェクト - Rubyにおいてクラスはオブジェクトだった?!?
クラスのクラス - その名は Classクラス ! (頭痛くなりますねわかります)
ここまでは、
オブジェクト(インスタンス)
はクラスから生成されるデータ
と説明してきましが、なんとクラスもなんです。
実は、先ほどまで利用していたPersonクラス
は実はオブジェクト(インスタンス)
なのです !オブジェクトの後に
class
メソッドをつけると所属先のクラスを知ることができましたよね。
プログラムを実行して確認しましょう。puts Person.class # Class「Personクラスは
Classクラス
に所属しているオブジェクト」ということが分かりました。
- Classクラス自体もクラスに属しているのですがこれについては説明を省きます。
PersonクラスはClassクラスのインスタンス
ということなので、Personクラスの実態は以下になります。Class.newクラスは実は定数
Personクラス
はClass.new
と分かりました。
では、Personという名前はどこからくるのでしょう...? 答えは定数
です。
定数は覚えてますでしょうか?アルファベット大文字 ([A-Z]) で始まる識別子ですね。
以下のようにClass.new
を定数Person
に割り当てます。Person = Class.new今まで見てきた以下のコードは
class Person end実は
Person = Class.newだったということになります。!(◎_◎;)
「Rubyではクラスは定数なんだよ!」の意味がわからん...?
と思っていた方はその事実に(つд⊂)ゴシゴシゴシ(;゚Д゚)…ハッ !?
となったのではないでしょうか?今まで見てきた
classの実態
は「Classクラスのオブジェクト(インスタンス)を定数に割り当てること」
に等しかったってことか...?前章のコードと同じように動作しました。
これでクラスはオブジェクトと言うことが分かりました。
*なのでインスタンスの特徴であるインスタンス変数の保持や、インスタンスメソッドを呼び出すことも可能です。7章 Railsで利用してる身近なオブジェクト(一部を抜粋)?
1. モデル
わかりやすいところでいうとモデルですね。
Railsのmodelってclassって書いてありますよね。
model名.new
とかはクラスからインスタンスを生成しているってことです。
model内にインスタンスメソッドを定義してるなら、インスタンスからそのメソッドを呼び出せるわけです。2. コントローラー
controllerも見てみるとclassって書いてありますよね。
例えば、HogeControllerのindexアクションを実行するって事は、
HogeControllerクラスから生成されたインスタンスからインスタンスメソッドindexを実行している訳です。先ほど
Rubyのクラスは定数
ということが分かりました。
Railsのエラー文でも定数(constant)というワードが出てきます。
uninitialized conostant コントローラー名
っていうエラーは見たことあるでしょうか?
マッチしたUrlのパスの行き先のコントローラーが探索できなかった時に出るエラーですね。
Routingのget '/users', to: 'users#index'
がマッチした時にUsersController
が探索できないような時です。(よく誤字とかで)コントローラーをちゃんと定義できてないという趣旨のエラー文が何故
初期化されてない定数 コントローラー名
ってエラー文になるねん?という疑問は
先ほどのRubyのクラスは定数
だということを知って納得できたのではないでしょうか?
とりあえず、Railsを利用している時もあちこちでオブジェクトが利用されているんだな! ということだけ知っていればひとまずOKです!
まとめ
Rubyのオブジェクトをこれまで紹介してきました。
ざっくりまとめると
Rubyはオブジェクトの世界で成り立っているんだなぁ〜。
「オブジェクトのメッセージングによるプログラミング手法」 がオブジェクト指向なんだなぁ〜。
ということです。Rubyを通してまだまだ知れることがあります。
今回の話題に関するものとして、特に継承
やmodule
について調べてみると良いでしょう。
実際に手を動かして、実験して理解を深めましょう !!! ☕️( ˙౪˙)? (疲れたので一服)参考
書籍 たのしいRuby
https://www.ruby-lang.org/ja/
https://docs.ruby-lang.org/ja/2.7.0/doc/index.html
https://railsguides.jp/
...etc
- 投稿日:2020-11-30T00:35:45+09:00
Recursive(再帰)とClass化(冒頭)
Document_Links
Recursive(再帰)
フィボナッチ数列を解く
今回はフィボナッチ数列を解いてくわけだが,フィボナッチ数列って知ってるよね?
私が初めにその名前を聞いたのは映画「ダ・ヴィンチ・コード」かな?+(まあ,あれは初項の0が無かったが)+
ということで,フィボナッチ数列ってのは
F(0)=0, F(1)=1, F(n+2)=F(n)+F(n+1) (n>=0)
で定義される漸化式です.
解説
第1項と第2項について
前述したように,第1項と第2項は0,1なので,とりあえず,その部分を判定する関数を書く.
def fib(n) if n == 0 return 0 end if n == 1 return 1 end end require './aeroc' [[0,0],[1,1]].each do |pair| puts assert_equal(pair[1], fib(pair[0])) endassert_equalの引数が(pair[1],pair[0])となっているが,これはaeroc.rbのassert_equalと整合を取るため.
実行結果
$ ruby fibonacci01.rb expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal.第3項について
定義に当てはめると,=F(2)=F(0)+F(1)=となる.
これを反映させると,(かなり強引だが)
def fib(n) if n == 0 return 0 end if n <= 2 return 1 end end require './aeroc' [[0,0],[1,1],[2,1]].each do |index, expected| puts assert_equal(expected, fib(index)) end引数を|pair|としていたがわかりにくいため,|index,expected|に変更
実行結果
$ ruby fibonacci2.rb expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal.ちょいとコードがゴチャついてきたので修正.
def fib(n) return 0 if n == 0 return 1 if n <= 2 end require './aeroc' [[0,0],[1,1],[2,1]].each do |index, expected| puts assert_equal(expected, fib(index)) endmethodを大幅に削減できた.
一般式について
定義では=F(n+2)=F(n)+F(n+1)=とあるが,これをコードにするのは無理(理由は分かるじゃろうて).
コードにするなら,=F(n)=F(n-1)+F(n-2)=だよね.
def fib(n) return 0 if n == 0 return 1 if n == 1 return fib(n-1)+fib(n-2) end require './aeroc' [[0,0],[1,1],[2,1],[3,2],[4,3], [5,5],[6,8],[7,13],[8,21]].each do |index, expected| puts assert_equal(expected, fib(index)) end引数を|pair|としていたがわかりにくいため,|index,expected|に変更
実行結果
$ ruby fibonacci.rb expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal. ・ ・ ・ expected :: 13 result :: 13 succeeded in assert_equal. expected :: 21 result :: 21 succeeded in assert_equal.完成!
Class化
冒頭
オブジェクト指向を学んでいくわけだが,キーとなるのが,
- 隠蔽(capsulation)
- 継承(inheritance)
- 多形(polymorphism)
とのこと.
例えば,
def puts_hello name puts "Hello #{name}." end def gets_name name = ARGV[0] || 'world' return name end name = gets_name puts_hello name実行結果
$ ruby hello.rb Hello World. $ ruby hello.rb Name Hello Name.mainでloopがある.
こいつを消したいというわけで,修正をかける.
class Hello def initialize @name = gets_name puts_hello end def puts_hello puts "Hello #{@name}." end def gets_name name = ARGV[0] || 'world' return name end end Hello.new実行結果は同じになる
締め
今回はRecursive(再帰)とClass化(冒頭)について学んだ.
次回,執筆時には知らない.
- source ~/school/multi/my_ruby/grad_members_20f/members/evendemiaire/post/recursive.org
- 投稿日:2020-11-30T00:35:45+09:00
Recursive(再帰)とClass化の冒頭
Document_Links
Recursive(再帰)
フィボナッチ数列を解く
今回はフィボナッチ数列を解いてくわけだが,フィボナッチ数列って知ってるよね?
私が初めにその名前を聞いたのは映画「ダ・ヴィンチ・コード」かな?
(まあ,あれは初項の0が無かったが)ということで,フィボナッチ数列ってのは
F(0)=0, F(1)=1, F(n+2)=F(n)+F(n+1) (n>=0)
で定義される漸化式です.
解説
第1項と第2項について
前述したように,第1項と第2項は0,1なので,とりあえず,その部分を判定する関数を書く.
def fib(n) if n == 0 return 0 end if n == 1 return 1 end end require './aeroc' [[0,0],[1,1]].each do |pair| puts assert_equal(pair[1], fib(pair[0])) endassert_equalの引数が(pair[1],pair[0])となっているが,これはaeroc.rbのassert_equalと整合を取るため.
実行結果
$ ruby fibonacci01.rb expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal.第3項について
定義に当てはめると,=F(2)=F(0)+F(1)=となる.
これを反映させると,(かなり強引だが)
def fib(n) if n == 0 return 0 end if n <= 2 return 1 end end require './aeroc' [[0,0],[1,1],[2,1]].each do |index, expected| puts assert_equal(expected, fib(index)) end引数を|pair|としていたがわかりにくいため,|index,expected|に変更
実行結果
$ ruby fibonacci2.rb expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal.ちょいとコードがゴチャついてきたので修正.
def fib(n) return 0 if n == 0 return 1 if n <= 2 end require './aeroc' [[0,0],[1,1],[2,1]].each do |index, expected| puts assert_equal(expected, fib(index)) endmethodを大幅に削減できた.
一般式について
定義では=F(n+2)=F(n)+F(n+1)=とあるが,これをコードにするのは無理(理由は分かるじゃろうて).
コードにするなら,=F(n)=F(n-1)+F(n-2)=だよね.
def fib(n) return 0 if n == 0 return 1 if n == 1 return fib(n-1)+fib(n-2) end require './aeroc' [[0,0],[1,1],[2,1],[3,2],[4,3], [5,5],[6,8],[7,13],[8,21]].each do |index, expected| puts assert_equal(expected, fib(index)) end引数を|pair|としていたがわかりにくいため,|index,expected|に変更
実行結果
$ ruby fibonacci.rb expected :: 0 result :: 0 succeeded in assert_equal. expected :: 1 result :: 1 succeeded in assert_equal. ・ ・ ・ expected :: 13 result :: 13 succeeded in assert_equal. expected :: 21 result :: 21 succeeded in assert_equal.完成!
Class化
冒頭
オブジェクト指向を学んでいくわけだが,キーとなるのが,
- 隠蔽(capsulation)
- 継承(inheritance)
- 多形(polymorphism)
とのこと.
例えば,
def puts_hello name puts "Hello #{name}." end def gets_name name = ARGV[0] || 'world' return name end name = gets_name puts_hello name実行結果
$ ruby hello.rb Hello World. $ ruby hello.rb Name Hello Name.mainでloopがある.
こいつを消したいというわけで,修正をかける.
class Hello def initialize @name = gets_name puts_hello end def puts_hello puts "Hello #{@name}." end def gets_name name = ARGV[0] || 'world' return name end end Hello.new実行結果は同じになる
締め
今回はRecursive(再帰)とClass化(冒頭)について学んだ.
次回,執筆時には知らない.
- source ~/school/multi/my_ruby/grad_members_20f/members/evendemiaire/post/recursive.org
- 投稿日:2020-11-30T00:15:38+09:00
Nature Remo Local APIを用いて、LAN内のRailsアプリからNature Remoを操作する
概要
LAN内だけでNature Remoを操作できるRailsアプリケーションを作成しました。Nature Remo Local APIを利用しています。
あらかじめ家電のリモコンの赤外線信号をDBに保存しておくことで、Nature Remoのサーバとの通信がうまくできない場合でもNature Remoから赤外線信号を送信できます。ラズパイ等で起動しておけば非常時に活躍すると思います。
リポジトリ:chappy30313331/nature_remo_local
デモ
環境
下記の環境で動作確認しています。
- Nature Remo ファームウェア
Remo/1.0.79-gbbcb0e8
- OS
- Raspberry Pi 4:
Raspbian 10.6
- macOS:
Mojave 10.14.6
- PostgreSQL
- Raspberry Pi 4:
psql (PostgreSQL) 11.9 (Raspbian 11.9-0+deb10u1)
- macOS:
psql (PostgreSQL) 13.1
- Ruby 2.6.6
- Rails 6.0.3.4
※ Raspberry Pi 4でRuby 2.7系を利用してRails(5系or6系)を起動するとSegmentation Faultが発生したので2.6系を利用しています。
セットアップ
リファレンスに従ってNature Remoのホスト名もしくはIPアドレスを調べ、環境変数に設定しておきます。
$ export NATURE_REMO_HOST=192.168.XX.XX # OR $ export NATURE_REMO_HOST=Remo-XXXXXX.local$ bundle install $ bin/rails db:setup $ bin/rails server使い方
- サーバを起動し、トップページにアクセス
- 家電を追加
- 家電にボタンを追加
- リモコンをNature Remoに近づけて、追加したいボタンを押下し青く光ればOK
- 「読込」ボタンをクリックすると、読み取った信号が「信号」欄に表示されるので、名前をつけて保存
- 追加したボタンを家電の画面でクリックすると、Nature Remoから赤外線信号が送信されます
現状、Nature Remoのサーバ側に保存されている信号をエクスポートする機能はCloud APIにないようなので、一つ一つ追加していくことしかできないです。
実装
Nature Remoにリクエストして返ってきた信号を保存しておいて、ボタンを押したときにそのまま送信するだけです。簡易的な画面を作ってCRUDと送受信機能を実装してあります。
- Nature Remoに送信された信号を読み取る
read_signal.rbclass ReadSignal include Service def call uri = URI::HTTP.build(host: ENV['NATURE_REMO_HOST'], path: '/messages') HTTP.timeout(10) .headers('X-Requested-With' => 'local') .get(uri) end end
- Nature Remoから信号を送信する
send_signal.rbclass SendSignal include Service def initialize(signal) @signal = signal end def call uri = URI::HTTP.build(host: ENV['NATURE_REMO_HOST'], path: '/messages') HTTP.timeout(10) .headers('X-Requested-With' => 'local') .post(uri, body: @signal) end end参考リンク
- 投稿日:2020-11-30T00:14:55+09:00
Railsで起きた最初のエラー
こんばんは、ピチピチの社会人です。
本日はRailsで起きたエラーについてです。
問題
RailsでCRUD処理について学んでいる時、ルート、コントロール、ビューの順にコードを書き、rails sをした時に以下のエラー文が出ました。
エラー表示怖すぎ、、とりあえずエラー文を読んでみる。
色々調べてみるとどうやらビューファイルに問題があるらしい。routes.rbRails.application.routes.draw do get '/users/new', to: 'users#new' post '/users', to: 'users#create' endusers_controller.rbclass UsersController < ApplicationController def new @user = User.new end def create User.create(user_params) end private def user_params params.require(:user).permit(:name, :age) end endnew.html.erb<p>新規投稿</p> <%= form_with model: @user, url: "/users", method: :post, local: true do |f| %> <p>お名前:<%= f.text_field :name %></p> <p>年齢:<%= f.text_field :age %></p> <%= f.submit "送信" %> <% end %>どこも間違えてる気がしないんですけど、、
原因
いくら考えてもコードの間違いが見つからず、いくら調べてもわからない。
結局一から作成し直すと、先ほど作ったnew.html.erbがusersではなくlayoutsディレクトリに格納されていたことが判明。そりゃエラー出るわ。対策
分からなかったら素直に人に聞くこと。今回も自分で解決しようとして一時間ほど時間を無駄にしてしまったからある程度自分で考えて、分からなければ恥を忍んで聞くこと。
以上、最近プログラミング学習を始めたピチピチの社会人でした。
- 投稿日:2020-11-30T00:13:36+09:00
初心者がRailsサーバー立ち上げるための環境構築で苦戦した話
概要
progateの手順通りにすすめていくと、見事にハマって全然手順どおりに行かず。。。
ようやく「Yay! You're on Rails!」の画面を拝むことができたので、
環境構築で躓いた部分を備忘録として書き残します。初心者が環境構築で挫折してしまう気持ちがわかりました。。。環境
・macOS Catalina ver10.15.7
・ruby ver2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]
・rbenv ver1.1.2
・Rails ver6.0.3.4
・homebrew ver2.5.12
・yarn ver1.22.10
・nodebrew v8.9.4
・node.js v15.3.0ハマったことろ
1.Homebrewインストール
2.rbenv / ruby-buildインストール
3.webpackerインストール
4.nodebrew / node / yarnインストール1.HomeBrewインストール
以下のエラーでインストール失敗。
Error: RPC failed; curl 56 OpenSSL ssl_read: SSL_ERROR_SYSCALL上記の文をコピペして検索すると、色々対策案が出てきます。(ネットの通信速度が原因?)
バッファを増やすことで改善するようですが、自分の場合は時間開けて、
再インストールしたらできました。2.rbenv ruby-buildインストール
インストール自体は問題なしでしたが、「PATHを通す」作業で少しハマりました。
自分が使っているシェルによって少し手順が変わります。
ざっと調べた感じ、「bash」「zsh」の2択でしょうか。
ちなみに、macOSを 「Catalina」 にアップデートすると、
デフォルトシェルが bash から zsh になっているようです。
[ パスを通すとは? : https://qiita.com/soarflat/items/d5015bec37f8a8254380 ]まず使っているシェルの確認のために以下のコマンドをターミナルに打ちこみます。
$ echo $SHELL出力結果が
/bin/zsh
の場合
以下のコマンド入力をして、PATHを通します。$ echo 'eval "$(rbenv init -)"' >> ~/.zshrc $ source ~/.zshrc何をしてるか簡単に説明すると、
.zshrc
というファイルに、
eval "$(rbenv init -)"
という文言を追記しています。
source ~/.zshrc
でファイルの更新をしているようなイメージです。出力結果が
/bin/bash
の場合
以下のコマンド入力をして、PATHを通します。$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile $ source ~/.bash_profileつまりは、シェルによって、編集するファイルが異なるということですね。
ちなみに.zshrc(.bash_profile)っていうのは、
設定ファイルと言われているもので、.zshrc(bash_profile)だと、
ターミナル起動時に読み込まれるファイルになっています。このファイルに環境変数、
今回の場合だとPATHを登録しておくことで、登録したディレクトリ直下のスクリプトが、
絶対パスを指定しなくても実行できるようになります。
[ 参考先:https://web-nari.net/2019/01/12/bash-profile/ ]残るはRubyとRuby on railsのインストールを実施。
Railsコマンドでアプリケーションの作成まではすんなりと行きましたが、
最後のRailsサーバー立ち上げで、webpacker
が見つかりませんと言われて
インストール失敗。。。
どうもRails6でwebpackerが標準となり、
webpackerがインストールされてないとエラーが出るようです。
webpackerってなんだよ。。。3.webpackerインストール
webpackerとはなんぞやというのは、こちらのページを参考にしました。
インストールは以下のコマンドで実行できます。
$ rails webpacker:install、、、うまくいかずまたエラーです。第4項に続きます。
4.nodebrew / node / yarnインストール
今度は
yarn
とnode
と言われるものをインストールしろといわれました。
node.js関連のものみたいです。こいつらのインストール方法を調査。
こちらに行き着いたんですが、自分はXcodeが入っていなかったので、
nodeのインストールはnodebrew
でやることにしました。
ちなみにnodebrewは、node.jpのver管理ツールです。
nodebrewはhomebrewでインストールできるみたいです。(ややこしい、、、)
手順はこちらを参考にさせていただきました。$ brew install nodebrew次にセットアップして、PATHを通します。
$ nodebrew setup $ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zshrc $ source ~/.zshrc※~/.zshrcの部分は環境に応じて変更してください。
いよいよnode
のインストールです。
インストールできるVerを確認して、Ver指定をしてインストールします。
自分はとりあえず最新Verをインストールしました。$ nodebrew ls-remote ↑Ver確認 $ nodebrew install-binary v15.3.0 ↑この場合はv15.3.0をインストール $ nodebrew use v15.3.0 ↑最後に使用するVerを指定するしておく必要があるらしいお次は
Yarn
です。
公式ではnode.jsベースのパッケージマネージャーからのインストールは非推奨みたいです。nodebrewもnode.jsベースと言うことになると思うので、
YarnはHomeBrewでインストールします。
[ Yarn公式:https://classic.yarnpkg.com/ja/docs/install#alternatives-stable ]$ brew install yarn --ignore-dependencies
--ignore-dependencies
をつけると、yarn
だけをインストールすることができます。
通常のインストールすると以下のパッケージがインストールされます。
・icu4c
・node
・yarn
nodebrewでnodeはインストールしているので、homebrewでもインストールしてしまうと、
依存関係のエラーになってしまうようです。しかしこのままだと
icu4c
もインストールされていないので、インストールします。$ brew install icu4cここまでくればwabpackerも問題なくインストールできると思い、
再度挑戦するも次はこんなエラーが発生。Error: An exception occurred within a child process: RuntimeError: /usr/local/opt/node not present or broken Please reinstall node. Sorry :(入れたはずのnodeが見つからないと言っています。
/usr/local/opt/node
のディレクトリにないと言っているので、
このディレクトリに、先ほど入れたnodeが存在するようにする必要があります。
手順は、
1.ディレクトリの作成
2.シンボリックリンクの設定
になります。
[ 手順はこちらを参考させていただきました。 ]1.ディレクトリの作成
$ mkdir /usr/local/opt/node2.シンボリックリンクの設定
/usr/local/opt/node
にアクセスすると、
nodebrewで入れたnodeが存在するディレクトリへリンクするように設定します。$ ln -s ~/.nodebrew/current/ /usr/local/opt/node/そして再度、
$ rails webpacker:install以下の表示がでて成功です。
Webpacker successfully installed ? ?この状態で再度
rails s
を実行すると、、、無事成功です。
- 投稿日:2020-11-30T00:07:21+09:00
Railsの名前空間
概要
アプリケーションにて管理者専用画面を作ろうとした際、名前空間(namespace)という概念を採用したのでどのようなものなのか簡単にまとめてみます。
名前空間とは
元々のクラスに対しモジュールを追加したクラスを新たに作成する。その時、元々のクラスとモジュールを追加したクラスは別物と区別されます。その状態を別の名前空間にあるという。
例# 下記二つのクラスは別物と区別される Admin::UsersController UsersControllerこのように二つのコントローラを分ければ、管理者と一般ユーザーを容易に別のコントローラで分けることができます。
ディレクトリの設定
名前空間を使った場合、ディレクトリは名前空間ごとにサブディレクトリを作ります。
名前空間を使ったルーティングの設定
ルーティングの設定はnamespaceメソッドを使用し、引数に名前空間の名前をシンボルで設定し、ブロックで囲みます。
例namespace :admin do root "top#index" resources :users endurlパスは/adminからそれぞれのアクションへルーティングが設定されます。
パスの指定は下記のような例があります。例<%= link_to "管理者用ページ", :admin_root %> <%= link_to "ユーザー新規作成(管理者用)", :new_admin_users %> <%= link_to "ユーザー一覧(管理者用)", :admin_users %> <%= link_to "ユーザー編集(管理者用)", [:edit, :admin, :user] %>例class Admin::UsersController < Admin::Base #省略 redirect_to [:admin, @user]補足
名前空間を使用する、特にコントローラを分ける際、コントローラによって操作や表示を切り替える場面は多くあると思います。kind_ofメソッドを使えばコントローラによって条件分岐等をする際便利です。
例<% if controller.kind_of?(Admin::UsersController) %>まとめ
名前空間について簡単にまとめました。
簡単なアプリケーションであれば、一つずつ条件分岐すれば良いのですが、複雑なアプリケーションにそのようには行かないので、便利な機能でありプログラミングらしい機能だなと思いました。