20201130のRubyに関する記事は26件です。

第10回(1)、Rubyでフィボナッチ数列

Mac OS-11.0.1 ruby-2.6.6p146

フィボナッチ数列

本記事は大学院前期過程の講義[マルチスケールシミュレーション特論]に関する記事です
フィボナッチ数列はあの有名な数列。それを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
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActiveRecord inverse_ofの使い所

Rubocopの違反(RuboCop::Cop::Rails::InverseOf)が発生したので、inverse_ofについて調べてみました。

普通の関連付けではinverse_ofを使用しなくても、自動的に追えるようになっているので特に設定は必要ありません。

model.rb
class Parent < ApplicationRecord
  has_many :children
end

class Child < ApplicationRecord
  belongs_to :parent
end

しかし、関連付けでscopeをつける場合はinverse_ofを使用しなければいけません。以下のようにinverse_ofを設定してあげると逆関連づけを指定できます。

model.rb
class 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

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

ActionMailerのSMTP設定を動的に変更する

この記事について

Rails からメールを送る際、ActionMailerを使ってメールを送るケースが多いと思だろう。
しかし メールを送るサーバーを動的に設定したい場合はどうすればいいかについて解説している記事は少ないため、この記事で解説する。

一般的にRailsからActionMailerを使ってSMTP経由でメールを送る場合、下記の記事が参考になる。

この場合、SMTPサーバーの設定を config/environment.rbconfig/environments/production.rbconfig.action_mailer.smtp_settings = { ... }として設定することになる。

これは、1つのアプリケーションから1つのメールサービスしか使用しない場合は問題なく動作するが、ユーザーやグループによってアプリケーションが使用するメールサーバーを変えたい場合は意図したように機能しないだろう。

この記事ではユーザーやグループによってアプリケーションが使用するメールサーバーを変えたい場合、つまりは1つのアプリケーションから複数のメールサーバーを使用する場合について1つの解法を示していく。

定石

Railsでメールを送る場合、Railsガイド / Action Mailer の基礎 / Action Mailerを設定する に沿ってメールサーバーの設定を config/environment.rbconfig/environments/production.rb に対して config.action_mailer.smtp_settings = { ... }として設定することになる。

config/environment.rb
ActionMailer::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_namepasswordaddressを上書きしている例が書かれているが、実はこの 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.rbconfig/environments/production.rb に対して設定する以外に、ActionMailer::Base#mail の引数である delivery_method_options: を使って設定する事で、動的なSMTPサーバー設定を施す事ができる。

これはサービスを利用するユーザーやグループ単位でのメールサーバの切替等に活用できる仕組みであり、Railsの高い汎用性を表している一面であるとも言えるのではないだろうか。

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

Rubyのアンインストール方法

https://qiita.com/Okame-chan/items/39052dc4d4c3cebfb1ee

こちらの記事を参考にさせていただきました。

実行したこと

$ ruby -v

インストールされてる、Rubyのバージョンを調べる。

$ which ruby

Rubyの場所を確認すると、 ~/.rbenv/shims/ruby 
rbenvにありますよ、となっていたので

$ rbenv uninstall 【Rubyのバージョン】

とすることで、無事アンインストールできました。

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

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"

なるほど。。。

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

Rails パンくずリストの作成

はじめに

Railsアプリのヘッダー部分にパンくずリストを追加しました。忘れないように書き記します。

開発環境
ruby 2.6.5
Rails 6.0.3.4

目次

1.Gemの導入
2.パンくずの設定
3.CSSの設定

1.Gemの導入

gretelというGemを使用する。 下記Gemfileに追記後、ターミナルで忘れずにbundle installを実行する。

公式GitHub

Gemfile
gem "gretel"

2.パンくずの設定

パンくずの設定を書き込むbreadcrumbs.rbファイルを作成する。作成方法は下記のようにターミナルでコマンドを実行する。

ターミナル
rails g gretel:install

今回下記のような4層でパンくずリストを構成する。
トップページ > 掃除提案 > 登録一覧 > 掃除箇所の登録

config/breadcrumbs.rb
crumb :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;
}

4fe7bb811a01b4e77db7797b103d012f.gif

以上

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

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へデプロイ予定)

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

rakeの使い方

Mac OS X-10.15.7 ruby-2.7.1p83

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に書き込み,以下のように実行します.

> rake

Rakefileが用意している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
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Float型にて、計算した際に、値に少々ズレが生じる件について

環境

Ruby 2.6
Rails 5.1.7

背景

機能実装中、数値を計算する処理が何か合わないなぁと思ったら表題の現象が起きてた。
これは初めて遭遇したので備忘録として。

現象

ruby
irb(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.0

Float型に100掛けると何故か100倍になっておらず少々の誤差があることに気づいた

対応

https://qiita.com/yusabana/items/fd4a0185c1f120403a74
こちらの記事を参考にBigDecimalを使用してあげると綺麗な数値が出る

ruby
irb(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

以上

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

shell + emacsの基礎

Mac OS X-10.15.7 ruby-2.7.1p83

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)といった意図です.

img
Fig. ディレクトリー構造と絶対パス,相対パス.
mkdir ディレクトリ名 ディレクトリ作成
touch ファイル名 ファイル作成
pwd 絶対パスの表示
cd ディレクトリ名 ディレクトリ変更
cd .. 直前にいたディレクトリへ移動
ls ディレクトリ内のファイル一覧
cp コピー元 コピー先 ファイルなどコピーする
rm ファイル(ディレクトリ)名 削除する
mv 移動元 移動先 ファイル等の移動,名前変更

etc…

emacs

emacsは高性能なeditorの一つです.

一連の流れを記すと,

  1. emacs REDAME.org
  2. なんかの編集操作
  3. c-x c-s (save)
  4. c-x c-c (quit) or c-z(stop)

(quit:編集終了.stop:一時中断.fgで再開できる.)よく使う操作.

  • c-p, n, b, f, a, e # 移動
  • c-d, k # 削除
img
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でもOK
  • git 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

とします.

img
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
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsでflatpickrを使ってみる

はじめに

フォームから日付を入力する際、カレンダーから直感的に日付選択できるようにする"datetimepicker"等の日付ピッカー。
その一種であるflatpickrをRailsで使う方法がQiitaに見当たらなかったので記事にしてみました。
なお、当方初学者かつ初投稿なので、間違いなどございましたらご指摘いただけますと幸いです。

環境

  • ruby 2.6.6
  • Rails 5.2.4.4

flatpickrについて

flatpickrは非常に軽量で導入も簡単です。
flatpickr以外の日付ピッカーとしてbootstrap-datetimepickerが有名ですが、bootstrapやjQueryに依存していたり、bootstrapのバージョンの互換性などなにかと面倒です。
私のような初学者でもポートフォリオへの導入がしやすいかと思います。

関連ページ

flatpickrは色々細かく設定できるようなので、上記サイトを御覧ください。

  • flatpickr-rails (github)
    Railsで簡単に使えるようgemパッケージ化してくれています。
    今回はこちらを使って導入していきます。

flatpickrインストール

今回は先程のGemを使用するので、Gemfileに以下を記述し、インストールします。

gemfile
gem '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.js
document.addEventListener('turbolinks:load', () => {
  flatpickr('#flatpickr')
})

これでフォームをクリックするとflatpickrが表示されるはずです!
スクリーンショット 2020-11-30 14.42.31.png

カスタマイズ例

jsでのカスタマイズ例なんかは既にいろいろ記事が上がっていたり、公式サイトにも載っているのですが、少しだけ例を挙げておきます。

日本語化とスマホ対応

datetime.js
document.addEventListener('turbolinks:load', () => {
  // カレンダーの日本語化
  flatpickr.localize(flatpickr.l10ns.ja)
  // カレンダー表示
  flatpickr('#flatpickr', {
    // スマートフォンでもカレンダーに「flatpickr」を使用する設定
    disableMobile: true,
  });
})

//= require flatpickr/l10n/jaで日本語化を読み込んでいるので、これで曜日などが日本語になります。
スクリーンショット 2020-11-30 14.43.22.png

選択可能日を設定

datetime.js
document.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:とかで一ヶ月前までを選択可能にしたりもできます。
スクリーンショット 2020-11-30 14.41.21.png
11月28日時点なら、29日、30日と来月以降の文字は選択不可になっています。

テーマ変更

application.scss
/* 
 ...
 ...
 *= require flatpickr
 *= require flatpickr/themes/dark.css
 */

flatpickrには色々なテーマが用意されており、scssに読み込ませるだけで変更できます。
公式サイト日本語約ページにサンプルがあります。
Themes
スクリーンショット 2020-11-30 14.45.09.png
上の例はdarkテーマを採用していますが、darkのところを他のテーマ名に変えるだけで適用できます。
スクリーンショット 2020-11-30 14.45.49.png
material_blue.css
スクリーンショット 2020-11-30 14.46.31.png
airbnb

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

[Rails]ページネーション機能

実装したいこと

完成形

投稿が多くなってくると一覧表示した時に見にくくなってしまうのでページを分けました。

目次

  • 1. kaminariのインストール
  • 2. ページネーションの表示
  • 3. デザイン
  • 4. ラベルの変更

1. kaminariのインストール

Gemfileの一番下に以下を記述し、ターミナルでbundle installを実行します。

Gemfile
gem 'kaminari'

2. ページネーションの表示

今回はbefore_actionを用いて投稿一覧を表示しています。
ページネーションを表示させたいデータに.page(params[:page])を追記します。
また、.per(10)を追記することで1ページに10件のデータを表示するという設定をします。
デフォルトでは25件が表示されるようになっています。

app/controllers/posts_controller.rb
def 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.yml
ja:
 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

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

Ruby on Rails モデル検証〜文字列長の検証を追加〜

モデルの検証に文字列長の検証を追加

データベースの定義でnameカラムの文字列を30文字以下に制御しているが

app/models/task.rb
class Task < ApplicationRecord
  validates :name, presence: true
end

このままだと、30文字を超える文字列を超える文字列が入力された場合、登録や更新の際に例外が発生してしまう。
これではユーザーが問題の原因に気づきづらく、動線も不便になってしまうので、30文字を超える入力の時に
わかりやすい検証エラーが表示されるようにしたいと思います。

まずTaskモデル(app/models/task.rb)にコードを追加します。

app/models/task.rb
validates :name, length: { maximum: 30 }

これで30文字を超えるとエラーメッセージが返ってきます。

文字数制限を加えたい場合は参考にしてみてください。

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

messaging apiで勤怠管理botを作った。

はじめに

実家の会社ためにLINEのMessaging APIを使って勤怠管理botを作りました。

なぜ作ったか

  • 最初は給与計算アプリを作ろうと思ったが、勤怠記録の情報がないとそもそも計算できないと気づいた。
  • 実家の会社では祖母が手動で給与計算をしているが、最近計算間違いが多くなった。
  • LINEのMessaging APIであれば、誰でも簡単に使用できると思った。
  • 作成期間:約2週間

開発環境

  • 開発言語
    • Ruby
  • フレームワーク
    • Ruby on Rails
  • データベース
    • sqlite3
  • 使用技術等
    • Linter
      • rubocop
    • Ngrok
    • Messaging API

基本機能

  • ユーザーごとの出勤・退勤時間の登録
    ユーザーごとにその日の出勤時間・退勤時間を登録できます。
    既にその日の出勤時間を登録してる場合と、出勤時間を登録せずに退勤時間しようとしても登録できないようにしています。
    出勤時間2.gif

  • 今日の勤務記録の修正
    勤務記録はその日の記録のみ修正可能です。
    出勤時間が登録されていない場合は修正は不可能にしています。
    修正2.gif

  • 今日・今月・先月の勤務記録の参照
    勤務記録は今日・今月・先月の記録が参照可能です。
    記録がない場合は記録なしと表示します。
    確認2.gif

検討している追加機能・改善点

  • 退勤時間の登録し忘れ防止機能(時間指定メッセージでいけると思う)
  • 早出や残業などの区別(実家の会社ではよほどのことがない限りいらないかも)

作った感想

Messaging APIを触るのは初めてだったが、思ったよりも簡単な記述で幅広い機能の実装が可能ということがわかった。
LINEが非常に一般的なツールなので、ユーザーの敷居も低く、ユーザーフレンドリーなbotを簡単に作れる点は非常に素晴らしいものだと感じた。

今後について

今回は、最初は給与計算アプリを作ろうと思ったが、勤怠管理が必要ということで勤怠管理botの作成に至った。今後はこのbotで集めた記録を元に給与計算を作ろうと思っている。

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

疎通確認が目的のタスク名には ping を入れるとわかりやすい

こんにちは、株式会社ベストティーチャーで元気に働く たわら です。業務駆け出しエンジニアです。

業務に駆け出すと、いろんな学びがあります。今回はpingです。

とある日

先輩 「hogeサーバーから毎日何らかのデータを取ってくるrakeタスクを作ってほしい」
先輩 「諸事情で、通信すること自体が目的なんだ」
ボク 「ハイ!」

何とか実装して、タスク名をrequest_to_hogeとしてプルリクを出すと、、、

先輩 「、、、何をリクエストしてるかわかりずらいですね、、、」
先輩 「後から参画するエンジニアにもわかりやすい名前にしよう」
先輩 「こういうときは ping を変数に入れるといいよ」

ping って??

対象のコンピューターときちんとつながっているかどうか、を確認するときに使用するコマンドのことです。

例えば、Raspberry PiUbuntuを入れて、ネットワークを設定して、ホストマシン(Mac)側からssh接続するための前準備として、まず通信接続を確認するときなどに当該IPアドレスを指定して、pingコマンドを利用します。

この作業を疎通確認、と言います。

なので、変数にpingを入れると疎通確認を目的としたタスクだ、ということが示せます。

先輩 「ということで、ping_hoge という名前にしよう」
先輩 「これなら後から参画したエンジニアもタスクの意味が把握しやすいからね」
ボク 「ハイ!」

最後に

後から参画する方にわかりやすい名前をつける、という気づきがありました。
変数がわかりにくいとコールドリーディングにコストがかかってしまいます。
この瞬間だけではなくて、長い時間のなかでわかりやすい変数の名前をつけるのが大事なのですね。

参考文献

用語集「pingとは?」
https://www.cman.jp/network/term/ping/

pingとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word124.html

pingを知ろう - Qiita
https://qiita.com/masapiko/items/57d6d6f666ee0412383b

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

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の例も理由は同じです

結論

必ず親側のモデルからデータをとるようにするクセをつけるといいと思います

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

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?を使って検証エラーの有無を調べエラーがある時にエラーメッセージを表示するようにしている。

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

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.rb
puts 'Hello,world!'
hello.py
print('Hello, World!')

putsとprintで言語の違いがありますが、おおむね同じですね。

コメント

comment.rb
# これはコメントです
comment.py
# これはコメントです

コメントの付けかたは、『#』で変わりません。

条件文

if.rb
def 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.py
def 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/

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

RailsにおけるRESTfulな設計とはなにか?

RESTfulとは

RESTful APIは、基本的に「RESTの原則」に従って実装されているWebシステムのHTTPでの呼び出しインターフェースのことを指します。

https://blog.api.rakuten.net/ja/jp-restful-api/#:~:text=REpresentational%20State%20Transfer%E3%81%AE%E7%95%A5,%E3%81%AE%E3%81%93%E3%81%A8%E3%82%92%E6%8C%87%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

なるほど..わからん。

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 入門

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

Ruby オブジェクトってなんなの??に答える

adventカレンダー初日の担当をさせていただきます !
DMM WEBCAMPでメンターをしているtanidaです !

Rubyのオブジェクトとは何か? オブジェクト指向とは何か?
そんな疑問に答えていければと思います。

ではでは、オブジェクトの世界を覗いてみましょう!

そもそもRubyにおいてオブジェクトとは

オブジェクト(インスタンス)とは、あるクラスから生成されたデータのこと!

*オブジェクトとインスタンスは同じモノだと、とりあえず覚えてください。

オブジェクト指向って何なんですか?

プログラムはオブジェクト間のメッセージのやりとり という考え方です。
この考え方を理解するためにも、オブジェクトについて理解を深めていきましょう。

1章 実際にオブジェクトを作ってみる?

PCにRubyのインストールされてない方はこのサイトのEditorにソースコードを書いて試せます。
https://try.ruby-lang.org/

Personクラス - 人クラス

object.rbというファイルを作成して以下のソースコードを実行してみます。

object.rb
class 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"> がターミナル上で確認できました。

  • 検証デモ object.gif

2章 もう少しオブジェクト(インスタンス)について調べてみる?

1. 所属するクラス

インスタンスはクラスに所属しているのでclassメソッドを利用すると、オブジェクトが所属するクラスはどこか教えてくれます。

puts person.class

2. インスタンス変数

インスタンス変数とはインスタンスが保持している変数の事です。
先ほどのコードでいうと、@name です。インスタンス変数は@マークがイニシャルでなければいけません。
インスタンス変数は同じインスタンス内であればその値を参照、変更ができます。

instance_variablesメソッドを利用するとインスタンス変数を教えてくれます。

puts person.instance_variables

3. インスタンスメソッド

インスタンスメソッドとは、クラス内に定義された、
クラスから生成されたオブジェクト(インスタンス)からしか呼び出せないメソッドのこと。

puts person.class.instance_methods(false)

instance_methodsの引数にfalseを付け加えると、
継承先のメソッドは表示しないようにしてくれます。(継承については説明を省きます)
今回はPersonクラスに定義されたインスタンスメソッドのみを聞きたいのでそうしています。

Personクラスから生成されたオブジェクト(インスタンス)からならgreetingを呼べます。

puts person.greeting

この呼び方はできない

puts greeting
  • イメージ図
    hito.png

  • 検証デモ
    object.gif

3章 アクセスメソッドの利用?

attr_accessor (いわゆるgetter/setter)

attr_reader(getter) と attr_writer (setter) が融合したもの

オブジェクトの外部からインスタンス変数を直接参照したり、インスタンス変数の値を更新することはできません。
でも、オブジェクトの外部から、簡単にインスタンス変数の値にアクセスしたいし、更新もしたい。。。
しかし、アクセスメソッドなら実現できます。

attr_accessor を追加するとオブジェクトから直接インスタンス変数の値を「参照」したり、「設定」したりできます。

object.rb
class 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 # 参照
  • 検証デモ object.gif

*ちなみに他のオブジェクト指向言語でも、getterとsetterというワード、概念はあります。

4章 重要な概念レシーバーとは?

メソッドの戻り値を受け取る対象のことです。

Personクラスにあるインスタンスメソッドgreetingを呼び出した時に
"Hi! I'm menter taro" といった文字列が戻り値となっていました。

その戻り値を受け取る対象をレシーバーと言います.
先ほどのソースコードでの person がレシーバーとなります。

puts person.greeting # "Hi! I'm menter taro" というメッセージをpersonが受け取る。

つまり、レシーバーとはインスタンスメソッドを呼び出しているインスタンス自身のこと !

もう少しレシーバーについて詳しくみてきましょう。

呼び出されたメソッドのレシーバー自身を参照する - self

インスタンスメソッド内でselfと記述すると、そのメソッドを呼び出したレシーバを取得できます。

object.rb
class 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
  • 検証デモ object.gif

オブジェクト指向の世界では
「オブジェクトにセッメージを送り」 そして 「オブジェクトがメッセージを受け取る」
このように捉えられるのでレシーバーと呼ぶらしいです。

オブジェクト指向プログラミングは
プログラムはオブジェクト間のメッセージのやりとり
`「オブジェクトのメッセージングによるプログラミングの手法」
と言われる理由が少しイメージできたのではないでしょうか?

5章 クラスメソッドとは?

レシーバがインスタンスではなくクラスそのものであるメソッドの事です。
書き方は色々とあるのですがこの記事ではself.メソッド名で定義します。
*先ほどのselfとは異なりインスタンスメソッド内ではなくクラス内に定義することになります。

object.rb
class 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
  • 検証デモ object.gif

じゃあ、クラスメソッドをどういう時に利用するの?

と言われると(まぁ好きなように使えるのですが)
インスタンスからメソッドを呼び出すと意味がちょっと違和感がある場合や、
あるクラスのオブジェクトを参照中に他のクラスに関する処理を行いたい時 とかはクラスメソッドにすると良いかと思います。そのほうがソースコードの管理が楽になるはずです。

例えば、5人分のPersonインスタンスを一括で生成したい時...

Personのインスタンスから直接呼ぶとチョット違和感ありませんか!...?
- いきなり真面目な顔で 「人間五人作れ」 という人がいたら太郎さんは困ります。
hito.png

  • Monsterクラスのインスタンスを参照中、そのインスタンスに他のクラスに関する処理をまとめてしてくれ!と言うのもチョット違和感ありませんか...?
    monster.png

  • Personクラスに直接頼みましょう。その方がソースコードの管理がしやすいでしょう。
    hito.png

では実際にbulk_createというクラスメソッドで5人分のPersonインスタンスを生成してみます。

object.rb
class 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クラスということです。

  • 検証デモ object.gif

という事でクラスオブジェクトがレシーバーになるメソッドがクラスメソッドと言うことになります。

なるほどぉ〜?? ん? チョット待って...クラス「オブジェクト」...?
オブジェクトってあるクラスから生成されたデータインスタンスの事って言ってましたよね...?
クラスオブジェクトは別物なんでちゃんと「クラス」って言った方がいいんじゃないんですか??

うん、うん、そうそう... うん、オブジェクトはクラスに所属してるんだけどね...
まぁそうなんだけどね... 実は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クラスのオブジェクト(インスタンス)を定数に割り当てること」に等しかったってことか...?

  • 検証デモ (Personクラスをclassを使わず、定数で定義してみた) object.gif

前章のコードと同じように動作しました。
これでクラスはオブジェクトと言うことが分かりました。
*なのでインスタンスの特徴であるインスタンス変数の保持や、インスタンスメソッドを呼び出すことも可能です。

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

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

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]))
end

assert_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))
end

methodを大幅に削減できた.

一般式について

定義では=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
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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]))
end

assert_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))
end

methodを大幅に削減できた.

一般式について

定義では=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
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

デモ

demo

環境

下記の環境で動作確認しています。

  • 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と送受信機能を実装してあります。

read_signal.rb
class 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
send_signal.rb
class 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

参考リンク

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

Railsで起きた最初のエラー

こんばんは、ピチピチの社会人です。

本日はRailsで起きたエラーについてです。

問題

RailsでCRUD処理について学んでいる時、ルート、コントロール、ビューの順にコードを書き、rails sをした時に以下のエラー文が出ました。

スクリーンショット 2020-11-29 23.43.10.png
エラー表示怖すぎ、、とりあえずエラー文を読んでみる。
色々調べてみるとどうやらビューファイルに問題があるらしい。

routes.rb
Rails.application.routes.draw do

  get '/users/new', to: 'users#new'
  post '/users', to: 'users#create'
end

users_controller.rb
class 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
end

new.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ディレクトリに格納されていたことが判明。そりゃエラー出るわ。

対策

分からなかったら素直に人に聞くこと。今回も自分で解決しようとして一時間ほど時間を無駄にしてしまったからある程度自分で考えて、分からなければ恥を忍んで聞くこと。

以上、最近プログラミング学習を始めたピチピチの社会人でした。

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

初心者が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インストール

今度はyarnnodeと言われるものをインストールしろといわれました。
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/node

2.シンボリックリンクの設定
/usr/local/opt/nodeにアクセスすると、
nodebrewで入れたnodeが存在するディレクトリへリンクするように設定します。

$ ln -s ~/.nodebrew/current/ /usr/local/opt/node/

そして再度、

$ rails webpacker:install


以下の表示がでて成功です。

Webpacker successfully installed ? ?

この状態で再度rails sを実行すると、、、

スクリーンショット 2020-11-29 23.38.34.png

無事成功です。

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

Railsの名前空間

概要

アプリケーションにて管理者専用画面を作ろうとした際、名前空間(namespace)という概念を採用したのでどのようなものなのか簡単にまとめてみます。

名前空間とは

元々のクラスに対しモジュールを追加したクラスを新たに作成する。その時、元々のクラスとモジュールを追加したクラスは別物と区別されます。その状態を別の名前空間にあるという。

# 下記二つのクラスは別物と区別される
Admin::UsersController
UsersController

このように二つのコントローラを分ければ、管理者と一般ユーザーを容易に別のコントローラで分けることができます。

ディレクトリの設定

名前空間を使った場合、ディレクトリは名前空間ごとにサブディレクトリを作ります。

名前空間を使ったルーティングの設定

ルーティングの設定はnamespaceメソッドを使用し、引数に名前空間の名前をシンボルで設定し、ブロックで囲みます。

namespace :admin do
  root "top#index"
  resources :users
end

urlパスは/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) %>

まとめ

名前空間について簡単にまとめました。
簡単なアプリケーションであれば、一つずつ条件分岐すれば良いのですが、複雑なアプリケーションにそのようには行かないので、便利な機能でありプログラミングらしい機能だなと思いました。

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