- 投稿日:2019-07-10T23:54:38+09:00
今日の学習
やったこと
・クラスメソッドについて
・オブジェクトについて
・継承について学んだこと
ruby クラス使い方
→メソッドなどの処理などを入れる箱のようなもの.
この入れ物のなかに処理を書くのが基本。qiita.rb# Stringという型(クラス)の値をnewで作成し変数whoへ代入 who = String.new("jobs") #whoにはString型の値が入っている p who上記はStringクラスからnewしてString型の値を作成し、変数whoへ代入している。
そしてp whoでwhoの中身の値を表示している。実行結果
"jobs"
次のクラスはUserクラスの型からnewしてUserクラスの値を作成し、変数userに値を代入している。
↓qiita.rbUserという型(クラス)の値をnewで作成し変数userへ代入 user = User.new userにはUser型の値が入っている p user (A) user.name = "user" p user.name (B)実行結果
<User:0x00007fbde51ca2f0>
”user"
実行結果(A)の出力結果が得られている。この場合Rubyのクラスの表示方法として決められている定型フォーマットに沿った何かしらのクラスであるという意味のUser:0x00007fbde51ca2f0という表示になっている。
(B)は、Userクラスのメソッドの出力である。
・クラスとインスタンス
クラスには処理を書いていくが、実際に処理を行うときはクラスからインスタンスというものを生成して、処理を行わせる。インスタンスの生成には「new」メソッドを使用する。class User def name @name end def name=(name) @name=name end end user = User.new user.name="yutaka" p user.name実行結果
"yutaka"
このようにクラスを使うときは基本的にnewメソッドを使用してインスタンスを生成して処理を行うことを特に意識しておく。☆よく言われる例としてはクラスがたい焼きの型、インスタンスがたい焼きなどと言われる。
つまりクラスからインスタンスが生成されといったイメージが大切。
またインスタンスはそれぞれ独立して値を持つことができる。class User def name @name end def name=(name) @name = name end end user1 = User.new user2 = User.new user1.name = "yutaka" user2.name = "hanako" p user1.name p user2.name実行結果
”yutaka”
"hanako"
・クラスの継承
あるクラスの定義を他のクラスの処理に引用すること。補足教材
・クラスのinitializeについてhttps://www.sejuku.net/blog/21170
・ruby クラス使い方まとめ https://www.sejuku.net/blog/15328
・https://www.youtube.com/watch?v=cLD2I5QvrCU
- 投稿日:2019-07-10T23:10:39+09:00
今日学んだ事
7/10(水)
●groupメソッド
・テーブルのレコードを指定したカラムでまとめた状態で取得する。
コード
モデル.group(カラム名)・idが一番小さいコードの1件が表示されるが、裏側ではまとめられた状態で取得されている。
・具体的に何個まとまっているか個数は分からない。●countメソッド
・配列などの要素数を返すメソッド。
・groupメソッドに続けて使うと、まとめられたそれぞれのレコードの数が取得できる。
コードモデル.group(カラム名).count・返り値はハッシュとなる
●keysメソッド
・ハッシュはkeysメソッドを持っている
・ハッシュのキーだけを取り出し、配列として返すメソッド●mapメソッド
・配列の中身を1つずつ取り出してブロックという構文を繰り返し実行する。
・ブロックの返り値を集めた新しい配列を作成する。
コード配列オブジェクト.map{|ele| ブロックの処理}●order('count_カラム名').count(カラム名)
・指定したカラムをグルーピングし、それぞれのレコード数でソートできる
- 投稿日:2019-07-10T22:59:43+09:00
【Rails】ユーザ作成
Railsのユーザ作成について
Railsでログイン機能を実装する場合に、ユーザ作成を行うと思います。
今回は、その、ユーザ作成機能について説明していきます。使用するコントローラ
toppagesコントローラ(サインアップページへ移行するurlがある)
-indexusersコントローラ
-index,show,new,createの二つです。toppages,usersのように、語尾に「s」を付けているのは、あとあと便利になってくるからです。
使用するモデル
Userモデル
-name:string email:string password_digest:stringユーザ名、メールアドレス、パスワードを入力とします。
Gemファイルに
gem 'bcrypt', '~> '
のような記述がありますが、railsに提供されている認証機能です。
この行のコメントアウトを消し、
$ bundle install
を実行し、railsのサーバを再起動させましょう。
また、railsで「bcrypt」を使用する際は、モデル作成時に、
password_digest:string
の記述が必須となります。この記述が無ければ認証ができなくなるので注意しましょう。コントローラ
topppagesコントローラは、ページの表示だけなので、usersコントローラのみを記述します。
users.rbclass UsersController < ApplicationController def index @users = User.all.page(params[:page]) end def show @user = User.find(params[:id]) end def new @user = User.new end def create @user = User.new(user_params) if @user.save flash[:success] = 'ユーザを登録しました。' redirect_to @user else flash.now[:danger] = 'ユーザの登録に失敗しました' render :new end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end end特筆すべきなのはcreateアクションのuser_paramsのところです。
ストロングパラメータの、password_confirmationは、確認用のパスワードのことです。
password_confirmationが記述されることで、パスワードの確認をプログラムがいい感じにやってのけてくれます。モデル
ユーザモデルに、has_secure_passwordと記述することでbcryptの認証機能を呼び出すことが出来ます。
user.rbclass User < ApplicationRecord has_secure_password endユーザ作成画面
CSSも適用してない最低限の画面です。
new.html.erb<h1>Sign up</h1> <p> <%= form_for(@user) do |f| %> <p> <div class="form-group"> <%= f.label :name, 'Name' %> <%= f.text_field :name, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :email, 'Email' %> <%= f.email_field :email, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :password, 'Password' %> <%= f.password_field :password, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :password_confirmation, 'Confirmation' %> <%= f.password_field :password_confirmation, class: 'form-control' %> </div> <P> <%= f.submit 'Sign up', class: 'btn btn-primary btn-block' %> <% end %>show.html.erb<h3 class="panel-title"><%= @user.name %></h3>これでユーザ作成に必要な主要な部分は完成しました!
- 投稿日:2019-07-10T21:39:41+09:00
RailsのログからRubyGemsによるwarningを非表示にする方法
現象
Ruby v2.6とRails5.1系でRubyがRails側のGemに対してものすごい数のwarningを出すようになりました。
具体的には、ActiveRecordの内部でBigDecimal.new
を呼んでいるようで、それに対してwarningが出ています。こんな感じのエラーが出る.../vendor/bundle/ruby/2.6.0/gems/activerecord-5.1.7/lib/active_record/connection_adapters/mysql/database_statements.rb:32: warning: BigDecimal.new is deprecated; use BigDecimal() method instead.Ruby v2.6では明示的にwarningを出すようになったからだそうです。
ref: Ruby 2.6 の変更点 - Numeric, BigDecimal BigDecmial.new が非推奨対処法
対処法としてはJeremy Evans氏作のruby-warning gemを使うと良さげです。
具体的には下記のような処理をconfig/initializers配下に置いておくと、Railsが起動される前に読み込まれて、Gemに起因するwarningがログに出なくなります。*開発環境ではログに出るようにしておくと、「あ、このGemアップデートしなきゃ」などが分かっていいかなと思います。
initializer配下にこんな感じのを置いておくunless Rails.env.development? Gem.path.each do |path| Warning.ignore(//, path) end end他にもっとスマートな方法をご存知の方がいらっしゃいましたら、ご指摘お願いします。
![]()
- 投稿日:2019-07-10T21:17:46+09:00
RailsをBootstrapVueで動かす
初投稿です
RailsでBootstrapとVue.jsを使う方法を調べると、
Vue.jsをrails new project --webpack=vue
で入れてきて、
BootstrapはGemfileにgem 'bootstrap'
を書いてbundle installしてjsやscssをいじって、、、
というのがオーソドックスなやり方のようちょっと面倒なのと、なぜかvueファイルのtemplateに書いたtooltipがちゃんと効いてくれなかったので、Bootstrapをgemで入れないようにして、yarnでBootstrapVueを入れるようにしてみた
BootstrapVue
おなじみBootstrapとVue.jsが合体したもの
公式サイトやったこと
プロジェクト作成(webpackでvueもインストール)
$ rails new bootstrapvue_rails --webpack=vueyarnでBootstrapVueをインストール
$ cd bootstrapvue_rails $ yarn add bootstrap-vue画面を用意して、ルーティングしてあげる
$ rails g controller Home index
config/routes.rbRails.application.routes.draw do root to: 'home#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end画面のjsファイルを作る
app/javascript/packs/home.jsimport Vue from 'vue/dist/vue.esm' import BootstrapVue from 'bootstrap-vue' import App from '../app.vue' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue/dist/bootstrap-vue.css' Vue.use(BootstrapVue) document.addEventListener('DOMContentLoaded', () => { const app = new Vue({ el: '#hello', data: { message: "Can you say hello?" }, components: { App } }) })vueファイルを作る
app/javascript/app.vue<template> <div id="app"> <p>{{ message }}</p> <div class="text-center my-3"> <b-button v-b-tooltip.hover title="Tooltip content">Hover Me</b-button> </div> </div> </template> <script> export default { data: function () { return { message: "Hello Vue!" } } } </script> <style scoped> p { font-size: 2em; text-align: center; } </style>viewで読み込む
app/views/home/index.html.erb<h1>Home#index</h1> <p>Find me in app/views/home/index.html.erb</p> <div id='hello'> {{message}} <app></app> </div> <%= javascript_pack_tag 'home' %>サーバーを立ち上げたらtooltipが効いてくれてる
$ ./bin/webpack-dev-server $ rails s
- 投稿日:2019-07-10T21:17:46+09:00
BootstrapVueをRailsに導入してみる
初投稿です
RailsでBootstrapとVue.jsを使う方法を調べると、
Vue.jsをrails new project --webpack=vue
で入れてきて、
BootstrapはGemfileにgem 'bootstrap'
を書いてbundle installしてjsやscssをいじって、、、
というのがオーソドックスなやり方のようちょっと面倒なのと、なぜかvueファイルのtemplateに書いたtooltipがちゃんと効いてくれなかったので、Bootstrapをgemで入れないようにして、yarnでBootstrapVueを入れるようにしてみた
BootstrapVue
おなじみBootstrapとVue.jsが合体したもの
公式サイトやったこと
プロジェクト作成(webpackでvueもインストール)
$ rails new bootstrapvue_rails --webpack=vueyarnでBootstrapVueをインストール
$ cd bootstrapvue_rails $ yarn add bootstrap-vue画面を用意して、ルーティングしてあげる
$ rails g controller Home index
config/routes.rbRails.application.routes.draw do root to: 'home#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end画面のjsファイルを作る
app/javascript/packs/home.jsimport Vue from 'vue/dist/vue.esm' import BootstrapVue from 'bootstrap-vue' import App from '../app.vue' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue/dist/bootstrap-vue.css' Vue.use(BootstrapVue) document.addEventListener('DOMContentLoaded', () => { const app = new Vue({ el: '#hello', data: { message: "Can you say hello?" }, components: { App } }) })vueファイルを作る
app/javascript/app.vue<template> <div id="app"> <p>{{ message }}</p> <div class="text-center my-3"> <b-button v-b-tooltip.hover title="Tooltip content">Hover Me</b-button> </div> </div> </template> <script> export default { data: function () { return { message: "Hello Vue!" } } } </script> <style scoped> p { font-size: 2em; text-align: center; } </style>viewで読み込む
app/views/home/index.html.erb<h1>Home#index</h1> <p>Find me in app/views/home/index.html.erb</p> <div id='hello'> {{message}} <app></app> </div> <%= javascript_pack_tag 'home' %>サーバーを立ち上げたらtooltipが効いてくれてる
$ ./bin/webpack-dev-server $ rails s
- 投稿日:2019-07-10T20:50:03+09:00
あなたはRailsチュートリアルで一体なにを学んだというのか【5章】
注意:プログラミング歴29日の初心者が書いています
注意:間違っていたら優しく教えてください(喜びます)
「Ruby on Rails チュートリアル実例を使ってRailsを学ぼう」
https://railstutorial.jp/素晴らしいチュートリアルに感謝します。
5.1.1 ナビゲーション
link_to
について
link_to
はRailsのヘルパー(viewsで使える関数)です。
最終的には<a>タグが生成されます。
第1引数はリンクテキスト、第2引数はURLです。link_to "sample app", '#', id:"logo"カッコが省略されています。関数です。
link_to("sample app", '#', id:"logo" )
image_tag
について
image_tag
もRailsのヘルパー(viewsで使える関数)です。
最終的には<img>タグが生成されます。
第1引数は画像のsrc、第2引数はここではalt属性です。image_tag("rails.png", alt: "Rails logo")第一引数として、単に画像ファイル名のみを指定した場合は、
asset
ディレクトリ内のimages
ディレクトリから自動で画像を引っ張ってきてくれます。5.1.2 BootstrapとカスタムCSS
アセットパイプラインについて
↓がわかりやすい
「railsのアセットパイプラインについて解説する」@hogehoge1234
https://qiita.com/hogehoge1234/items/9a94ebc93c5f937502cdアセットパイプラインとは、htmlファイルと、css,javascript, imgファイルを自動で統合できるようにする仕組みです。
そもそも、webサイトの表示は、主に以下の3つをブラウザが読み込むことで実現される。
htmlファイル
cssファイル
JavaScriptファイル
*imgファイル
これらを一つのファイルで実現することは可能だが、わかりやすいように通常は別々のファイルで作って、最後にそれぞれをhtmlファイルにリンクさせる。
Railsにおいては、
htmlファイルに相当するhtml.erbファイルはviewsディレクトリに保存します。
cssとJavascriptとimgファイルはassetディレクトリ内部にある、それぞれのディレクトリに保存します。
さらに言うと、cssファイルではなくsassというcssの便利バージョンになっています。sassファイルからcssファイルに変換(コンパイル)しないとブラウザが読み込めないのですが、アセットパイプラインにはコンパイラも含まれています。
つまり、assetディレクトリに入っているファイルたちが、あたかもパイプの中を通りながら1つのファイルに統合されて出てくるようなイメージです。
Railsサーバーの再起動が必要なタイミング
Rubyのバージョンを変更したり、
Gemfileを変更したり、
Railsの内部クラスから何かを変更した場合は、
再起動する必要があります。
5.1.3 パーシャル (partial)
render
についてrenderはヘルパー(viewsに使える関数)の呼び出しをします。
テンプレートを呼び出して表示させるためによく使われます。テンプレート(要は繰り返し使うhtml部分など)は、partial(パーシャル)という仕組みを使って、コードを一つのファイルにまとめておきます。
その際、パーシャルのファイル名は、
_(アンダースコア)
で始まるファイル名にします。render 'layouts/shim'これは、
/_shim.html.erb
というファイルを探してその内容をレンダリング(表示)します。
先頭の_(アンダースコア)
とhtml.erb
などの余分な内容は省略して記述します。もちろん、パーシャルにするコードは別ディレクトリに用意しておく必要があります。
5.2.1 アセットパイプライン
アセットディレクトリについて
assets
ディレクトリは、その内容によって、以下3つのディレクトリに含まれています。
app/assets
: 現在のアプリケーション固有のアセット
lib/assets
: あなたの開発チームによって作成されたライブラリ用のアセット
vendor/assets
: サードパーティのアセットそれぞれの
assets
ディレクトリの内部には、CSS、JavaScript、Imagesのディレクトリが存在します。マニフェストファイルについて
統合させたり読み込ませるCSSやJavaScriptを指定したり設定したりするファイルです。
プリプロセッサエンジンについて
.erb
や.scss
など、拡張子を読み取って、.html
や.css
にコンパイルできるように加工してくれます。その他の加工について
ファイルすべてに対して 不要な空白やインデントを取り除く処理を行い、ファイルサイズを最小化してくれます。結果として、読み込みが早くなります。
5.3 レイアウトのリンク
名前付きルート
root_path -> '/' root_url -> 'http://www.example.com/'例えば、ルートに関してはすでに
root
という名前付きルートが定義されています。
ここに_path
メソッドや_url
メソッドを使用することで、名前付きルートの中身を見てみることができます。get 'static_pages/help'上記を、以下の名前付きルートに変換します。
get '/help', to: 'static_pages#help'読み方は、
『GETリクエスト(ページを取得しろ)が/help
に送信されたとき、
StaticPagesコントローラーのhelpアクションを呼び出してくれ』です。test "should get help" do get help_path #これ assert_response :success assert_select "title", "Help | Ruby on Rails Tutorial Sample App" endテストコードの修正をします。
これは、help
という名前付きルートに対して、_path
メソッドを使用し、
/static_pages/help
というパスを取得しています。5.3.4 リンクのテスト
統合テスト
統合テストは、複数のコントローラの動きをチェックするテストのことです。
assert_select "a[href=?]", about_path
?
の中身は、第2引数のabout_path
になります。
つまり、<a href="/about">...</a>
というaboutページへのパスを含む<a>タグがあるかどうかのチェックです。$ rails test:integration上記コマンドで動かします。
5.4.1 Usersコントローラ
Usersコントローラの生成 (newアクションを追加)
「newアクション」とは、Railsの7アクションの1つです。何かを新規作成する際のアクションです。
get '/signup', to: 'users#new'ルーティングに
/signup
を追加したことによって、signup_path
でページへのパスを表現できるようになりました。
- 投稿日:2019-07-10T20:50:03+09:00
わたしがRailsチュートリアルで学んだこと【5章】
注意:プログラミング歴29日の初心者が書いています
注意:間違っていたら優しく教えてください(喜びます)
「Ruby on Rails チュートリアル実例を使ってRailsを学ぼう」
https://railstutorial.jp/素晴らしいチュートリアルに感謝します。
5.1.1 ナビゲーション
link_to
について
link_to
はRailsのヘルパー(viewsで使える関数)です。
最終的には<a>タグが生成されます。
第1引数はリンクテキスト、第2引数はURLです。link_to "sample app", '#', id:"logo"カッコが省略されています。関数です。
link_to("sample app", '#', id:"logo" )
image_tag
について
image_tag
もRailsのヘルパー(viewsで使える関数)です。
最終的には<img>タグが生成されます。
第1引数は画像のsrc、第2引数はここではalt属性です。image_tag("rails.png", alt: "Rails logo")第一引数として、単に画像ファイル名のみを指定した場合は、
asset
ディレクトリ内のimages
ディレクトリから自動で画像を引っ張ってきてくれます。5.1.2 BootstrapとカスタムCSS
アセットパイプラインについて
↓がわかりやすい
「railsのアセットパイプラインについて解説する」@hogehoge1234
https://qiita.com/hogehoge1234/items/9a94ebc93c5f937502cdアセットパイプラインとは、htmlファイルと、css,javascript, imgファイルを自動で統合できるようにする仕組みです。
そもそも、webサイトの表示は、主に以下の3つをブラウザが読み込むことで実現される。
htmlファイル
cssファイル
JavaScriptファイル
*imgファイル
これらを一つのファイルで実現することは可能だが、わかりやすいように通常は別々のファイルで作って、最後にそれぞれをhtmlファイルにリンクさせる。
Railsにおいては、
htmlファイルに相当するhtml.erbファイルはviewsディレクトリに保存します。
cssとJavascriptとimgファイルはassetディレクトリ内部にある、それぞれのディレクトリに保存します。
さらに言うと、cssファイルではなくsassというcssの便利バージョンになっています。sassファイルからcssファイルに変換(コンパイル)しないとブラウザが読み込めないのですが、アセットパイプラインにはコンパイラも含まれています。
つまり、assetディレクトリに入っているファイルたちが、あたかもパイプの中を通りながら1つのファイルに統合されて出てくるようなイメージです。
Railsサーバーの再起動が必要なタイミング
Rubyのバージョンを変更したり、
Gemfileを変更したり、
Railsの内部クラスから何かを変更した場合は、
再起動する必要があります。
5.1.3 パーシャル (partial)
render
についてrenderはヘルパー(viewsに使える関数)の呼び出しをします。
テンプレートを呼び出して表示させるためによく使われます。テンプレート(要は繰り返し使うhtml部分など)は、partial(パーシャル)という仕組みを使って、コードを一つのファイルにまとめておきます。
その際、パーシャルのファイル名は、
_(アンダースコア)
で始まるファイル名にします。render 'layouts/shim'これは、
/_shim.html.erb
というファイルを探してその内容をレンダリング(表示)します。
先頭の_(アンダースコア)
とhtml.erb
などの余分な内容は省略して記述します。もちろん、パーシャルにするコードは別ディレクトリに用意しておく必要があります。
5.2.1 アセットパイプライン
アセットディレクトリについて
assets
ディレクトリは、その内容によって、以下3つのディレクトリに含まれています。
app/assets
: 現在のアプリケーション固有のアセット
lib/assets
: あなたの開発チームによって作成されたライブラリ用のアセット
vendor/assets
: サードパーティのアセットそれぞれの
assets
ディレクトリの内部には、CSS、JavaScript、Imagesのディレクトリが存在します。マニフェストファイルについて
統合させたり読み込ませるCSSやJavaScriptを指定したり設定したりするファイルです。
プリプロセッサエンジンについて
.erb
や.scss
など、拡張子を読み取って、.html
や.css
にコンパイルできるように加工してくれます。その他の加工について
ファイルすべてに対して 不要な空白やインデントを取り除く処理を行い、ファイルサイズを最小化してくれます。結果として、読み込みが早くなります。
5.3 レイアウトのリンク
名前付きルート
root_path -> '/' root_url -> 'http://www.example.com/'例えば、ルートに関してはすでに
root
という名前付きルートが定義されています。
ここに_path
メソッドや_url
メソッドを使用することで、名前付きルートの中身を見てみることができます。get 'static_pages/help'上記を、以下の名前付きルートに変換します。
get '/help', to: 'static_pages#help'読み方は、
『GETリクエスト(ページを取得しろ)が/help
に送信されたとき、
StaticPagesコントローラーのhelpアクションを呼び出してくれ』です。test "should get help" do get help_path #これ assert_response :success assert_select "title", "Help | Ruby on Rails Tutorial Sample App" endテストコードの修正をします。
これは、help
という名前付きルートに対して、_path
メソッドを使用し、
/static_pages/help
というパスを取得しています。5.3.4 リンクのテスト
統合テスト
統合テストは、複数のコントローラの動きをチェックするテストのことです。
assert_select "a[href=?]", about_path
?
の中身は、第2引数のabout_path
になります。
つまり、<a href="/about">...</a>
というaboutページへのパスを含む<a>タグがあるかどうかのチェックです。$ rails test:integration上記コマンドで動かします。
5.4.1 Usersコントローラ
Usersコントローラの生成 (newアクションを追加)
「newアクション」とは、Railsの7アクションの1つです。何かを新規作成する際のアクションです。
get '/signup', to: 'users#new'ルーティングに
/signup
を追加したことによって、signup_path
でページへのパスを表現できるようになりました。
- 投稿日:2019-07-10T19:11:44+09:00
ruby正規表現のUnicode プロパティ(とPOSIX文字クラス)
皆様は正規表現をお使いでしょうか?
コードを書くことを生業にしている方なら常日頃とは言わずとも、幾度も相手にしたことがあると思います。私は結構よく使います。ただし、コードに書き込むのではなくテキストエディタで。
これが割と便利です。練習にもちょうどいい。何かそれっぽい名前の変数や関数を適当なあたりをつけてgrepする際に、大文字、小文字、キャメルケースにスネークケース、よくあるタイプミスなんかもうまく書けば緩衝して一発で探してきてくれます。
うまく書けば。
しかし、その正規表現は使い捨て。
たまにコーディングする時も結構単純なもの。目的に適うものを書き上げるのが当然の目的であって正規表現にこだわる必要すらない。
せいぜい半角数字を捕まえる時に[0-9]
と書くのをやめて\d
と書いてみて変わったことをした気分になる程度という体たらく。
書くたびにそれっぽいものをググって拾って魔改造、という感じ。UnicodeプロパティだとかPOSIX文字クラスだとかいう連中がいることは知ってはいるが使ったことはあっただろうか?
そこで、せっかくの機会なのでいくらか調べてここに書き留めておくことにしました。
rubyでの正規表現を想定しています。
rubularは便利ですね。
日本語相手の正規表現
先ほど少し書いたように、数字にマッチさせたい場合
[0-9]
という文字クラスを指定することがよくあるかと思います。
また、同様にアルファベットにマッチさせたい場合[a-zA-Z]
などと指定したりするかもしれません。
一般的な英数字、または記号程度ならこの書き方で正直事足りるような気がします。
しかし、このような文字クラスでの指定は日本語の場合少し癖のあるものになりがちです。例えば「正規表現 ひらがな」なんかで検索すると
[ぁ-ん]
と表記するといいよ。と書いてあることがままあります。(小さい"あ"から始まります)
実際にUnicodeを確認してみたところ、小さい"ぁ"は普通の"あ"の前にあります。なので小さい"あ"から指定を始める必要があるようですね。
ちなみにこの画像をみてもわかるようによくネット上で見かける
[ぁ-ん]
という文字クラスの指定では"ゔ"以降のひらがなを捉えられません。
それよりもこれを調べていて痺れたのは"ん"以降のひらがなですね。
"ゝ"や"ゞ"なんかはまだ見たことはありますが U+309F の彼は一体何者なのでしょうか、そもそもお前は本当にひらがななのか?なんと打てば出てくるのかすら全くわかりません。
wikipediaによると ゟ←これ はよりと読み、「現状ではコードポイントを設定していないため、PCのテキスト上に表示できない。」ということらしいが・・・。
手紙の最後に「〜ゟ」と記名したり、「ロシアゟ愛を込めて」なんて具合に使うのだろうか。
合略仮名という分類の文字らしいです。
打ち方がわからないでいうと"ゕ"と"ゖ"もなかなか謎です。"lka"とか"xka"とか打っても"ヵ"としか出てきません。挙句、変換を行うとmacは異なる注釈をつけて同じ文字を3回紹介してくれます。
と、ただひらがなを正規表現で捕まえようというだけで早くも苦労に塗れてきました。
Unicode プロパティ
少し話がそれ気味だったような気がしますが、ここでやっとUnicode プロパティが登場します。
ruby(というかonigmo正規表現ライブラリ)では\p{property-name}
と記述します。rubyではonigmoで使えるプロパティが使えます。
カタカナ\p{Katakana}
とか、漢字\p{Han}
とか、タガログ語\p{Tagalog}
とか。
上記リンク参照
かな
このUnicode プロパティを使ってひらがなを補足したかったら
\p{Hiragana}
と書くだけで、先述の問題も全て解消して、現代の日本人は見たことも無いようなひらがなまで捕まえてくれます。
ここで
\p{Hiragana}
に含まれている文字はどんなものがあるのか気になります。
どうも\p{}
はUnicodeのScriptsを参照するらしいです。
http://www.unicode.org/Public/UNIDATA/Scripts.txtこれによるとHiraganaの中身はこんな感じ。
3041..3096 ; Hiragana # Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE 309D..309E ; Hiragana # Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK 309F ; Hiragana # Lo HIRAGANA DIGRAPH YORI 1B001..1B11E ; Hiragana # Lo [286] HIRAGANA LETTER ARCHAIC YE..HENTAIGANA LETTER N-MU-MO-2 1B150..1B152 ; Hiragana # Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO 1F200 ; Hiragana # So SQUARE HIRAGANA HOKA # Total code points: 379
一番上の行を例に、左から
・3041..3096 : Unicode 文字コード範囲
・Hiragana : プロパティ名(\p{}
の中身)
・Lo : Unicode一般カテゴリ(詳しくはUNICODE CHARACTER DATABASEのGeneral Category Valuesの項を参照)
・[86] : 包含文字数(読んで字のごとく、86文字)
・HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE : プロパティ説明(これも読んで字のごとく、小さい"あ"から小さい"け"まで)そのほかにも複数のグループが含まれていて合計379もの文字がHiraganaプロパティには含まれているようです。
50音順とはなんだったのか。
ちなみに先ほどの結果を見てお気付きの方もいらっしゃるかもしれませんが、このHiraganaプロパティ、長音記号は含まれていません。
意図したものなのか否か。何れにせよ伸ばし棒も捕まえたければちゃんと
[\p{Hiragana}ー]
と文字クラスに含めておきましょう。
ただ、長音記号には似たような形のものがいっぱいあるので、純粋な長音記号しか許可しないようにしているとハイフンを入力しながら「伸ばし棒が通らない!」と怒られるかも。
\p{Katakana}
も同様に長音記号は含まれていません。
ただし、
[ぁ-ん]
これにはこれで魅力があると思っています。ひらがなにマッチする正規表現を書こうとした時、頭に思い浮かべたのが50音順+濁点・半濁点程度の一般的なひらがな達にとどまるなら
\p{Hiragana}
は過剰でしょう。
見たことのない記号のような文字などが通過してきてしまいます。こういう時には
[ぁ-ん]
を使っていくのが良いのではないでしょうか。
漢字
漢字を捉える正規表現は
[一-龠]
とか[一-龥]
などをネットでは見かけたりします。(これはUnicodeの話でありShift_JISでは違う表記になります。)
まぁ、常用する漢字ならこの範囲で十分カバーしており、これより先は言語学者でもなければ使わないだろうと言う腹ですね。当然これに収まらない漢字もありますが、ここで
\p{Han}
と書くとこれが解決。
約9万字にのぼるあらゆる漢字を拾ってくれます。
さらにこの
\p{Han}
拾うのは日本語の漢字に止まりません。
中国語の簡体字や繁体字、韓国語の漢字にもマッチしてくれて、ベトナム語の漢字(があることを今回初めて知った。)にもマッチするそうです。最近話題になった"令"を例にしてみましょう。新元号「令和」の令です。
この漢字は、韓国語にも同じ形の漢字があり、別のコードが与えられているということで少し前にちょっと一部界隈で話題になりました。
qiitaにもいくつか記事があります。s = "令令" puts s.codepoints.collect {|cp| sprintf("U+%04X", cp) }.join(", ") # => U+4EE4, U+F9A8 # 下記ページ参照 # https://ref.xaio.jp/ruby/classes/string/codepoints
これを正規表現に与えます。
こちらはダメ
こちらはうまく両方を取ってくれました。
その他
当然、言語関連以外にも算術記号
\p{Sm}
その他記号\p{P}
アンダースコア\p{Pc}
ハイフンやダッシュなど長音記号っぽい者達にマッチする
\p{Pd}
という子もいますが、これはあらゆるハイフンやダッシュの親戚もマッチしてしまうので⸚
←こんな見たこともない子もマッチしちゃうかも。
ちなみに、
\p{P*}
というプロパティたちは全て\p{P}
の部分集合です。
PはPunctuationの略で句読点のほか、約物なんて訳されたりします。記号全般っぽいですが算術記号
\p{Sm}
は見ての通り約物に含まれていません。こちらはSymbolカテゴリに含まれています。
ここのGeneral Category Valuesや
ここなどでP*に含まれているものが何者か注意しておくと良いかもしれません。
POSIX 文字クラス
似たようなものでPOSIXブラケットと言うものもあります。こちらはonigmoに限らず、Shift_JISだとかEUCだとかUnicodeでなくとも使えたりするようです。
こちらはruby正規表現ドキュメントに使用できるクラス名とその内容が列挙されています。
[:alnum:] 英数字 (Letter | Mark | Decimal_Number)
[:alpha:] 英字 (Letter | Mark)
[:ascii:] ASCIIに含まれる文字 (0000 - 007F)
[:blank:] スペースとタブ (Space_Separator | 0009)
[:cntrl:] 制御文字 (Control | Format | Unassigned | Private_Use | Surrogate)
[:digit:] 数字 (Decimal_Number)
[:graph:] 空白以外の表示可能な文字(つまり空白文字、制御文字、以外) ([[:^space:]] && ^Control && ^Unassigned && ^Surrogate)
[:lower:] 小文字 (Lowercase_Letter)
[:print:] 表示可能な文字(空白を含む) ([[:graph:]] | Space_Separator)
[:punct:] 句読点 (Connector_Punctuation | Dash_Punctuation | Close_Punctuation | Final_Punctuation | Initial_Punctuation | Other_Punctuation | Open_Punctuation)
[:space:] 空白、改行、復帰 (Space_Separator | Line_Separator | Paragraph_Separator | 0009 | 000A | 000B | 000C | 000D | 0085)
[:upper:] 大文字 (Uppercase_Letter)
[:xdigit:] 16進表記で使える文字 (0030 - 0039 | 0041 - 0046 | 0061 - 0066)
[:word:] 単語構成文字 (Letter | Mark | Decimal_Number | Connector_Punctuation)ドキュメントにも'エンコーディングによってこれらの POSIX 文字クラスの挙動が 異なります。'と記載されている通り、Unicode以外のエンコーディングではマッチする文字が異なるようなので、onigmoのドキュメントを参照する必要があります。
個人的にUnicode プロパティが使えるならこちらを殊更使う必要は生じないと考えています。
何よりこのドキュメントがかなりの誤解を招く。こちらの記事のコメントでも白熱しております。上記記事でわかるのは
[[:alpha:]]
や[[:alnum:]]
はかな漢字にマッチすると言うことです。
先ほどのドキュメントによると一見、英数字や英字にしかマッチしないように見えるのに。
ここでちゃんと(onigmoのドキュメント)[https://github.com/k-takata/Onigmo/blob/master/doc/RE.ja] を見てみましょう。
POSIXブラケットの項目には Unicode以外の場合、 Unicodeの場合 と分けてマッチする文字が記載されています。
Unicode以外の場合は
alnum 英数字
alpha 英字
そしてUnicode場合は
alnum Letter | Mark | Decimal_Number |
alpha Letter | Mark |
と書いてあります。
つまり、Unicodeはアルファベットを Letter | Mark の2カテゴリだと認識していると言うことだと考えられます。
ということは、
ABCDE
もあいうえお
も白發中
もLetterカテゴリなのでalphaだし、
ြ
こんな奴も[[:alpha:]]
[[:alnum:]]
は我々の直感に反して見事拾ってきます。
最後に
マッチする文字がどのようなものかを正確に認識した上で利用するならば
[[:alpha:]]
も便利ではあるのでしょう。
ただ、コーディングする場合は当然、いずれ他人の目に触れることになるでしょう。
その時、そのコードをみた人は「/[[:alpha:]]/
だから言語を問わず単語を構成する文字がかかるんだな。」と認識できるでしょうか。少なくともこの記事を書く前の私なら絶対に思わないでしょう。きっと
[A-Za-z]
と同等だと認識したはずです。そして、この認識が間違っていることに気がつくのも非常にこんなんだと思います。そんなことを気にするくらいなら迷わず
[A-Za-z]
を使います。
POSIX文字クラスに関しては、「この程度なら普通に正規表現を書けばいいじゃん。」です。Unicode プロパティも前述の通り微妙に直感に反してきたりしますが、POSIX文字クラスに比べると有用性が高い印象です。
積極的に使っていきたいですね。
参考
- 投稿日:2019-07-10T17:58:41+09:00
rails runner で Please specify a valid ruby command or the path of a script to run.
問題:lib以下のディレクトリを読み込んでくれない
スクリプトはこんな感じ
#lib/batch/push.rb class Test def self.push require 'json' result = TalkHistory.where(call_status: 'skyway_ringing').where(call_duration: nil).where('talked_at>?',Time.zone.now - 1.days).count("id") result_hash = {"count"=> result} File.open("test.json","w") do |file| JSON.dump(result_hash,file) end #jsonファイルのアップロード require 'aws-sdk' s3 = Aws::S3::Resource.new( :region => 'ap-northeast-1', :access_key_id => ENV['ACCESS_KEY_ID'], :secret_access_key => ENV['SECRET_ACCESS_KEY'] ) bucket = s3.bucket('testbucket0709') bucket.object('test').upload_file("test.json") puts bucket.object('test').exists? puts bucket.object('test').get.body.read end end実行すると...
rails ruuner 'Test.push' => Please specify a valid ruby command or the path of a script to run. Run 'bin/rails runner -h' for help. uninitialized constant Testautoload_pathsを確認
$ bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths' /Users/satou/projects/koetomosql/lib /Users/satou/projects/koetomosql/lib/ /Users/satou/projects/koetomosql/lib/tasks/ /Users/satou/projects/koetomosql/lib/batch/ /Users/satou/projects/koetomosql/lib/assets/ /Users/satou/projects/koetomosql/app/assets /Users/satou/projects/koetomosql/app/channels /Users/satou/projects/koetomosql/app/controllers /Users/satou/projects/koetomosql/app/controllers/concerns /Users/satou/projects/koetomosql/app/helpers /Users/satou/projects/koetomosql/app/jobs /Users/satou/projects/koetomosql/app/mailers /Users/satou/projects/koetomosql/app/models /Users/satou/projects/koetomosql/app/models/concerns /Users/satou/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activestorage-5.2.3/app/assets /Users/satou/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activestorage-5.2.3/app/controllers /Users/satou/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activestorage-5.2.3/app/controllers/concerns /Users/satou/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activestorage-5.2.3/app/javascript /Users/satou/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activestorage-5.2.3/app/jobs /Users/satou/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activestorage-5.2.3/app/models /Users/satou/projects/koetomosql/test/mailers/previews問題なさそう
でもコンソールで確認するとクラスを読み込めてない...Loading development environment (Rails 5.2.3) irb(main):001:0> Test Traceback (most recent call last): 1: from (irb):1 NameError (uninitialized constant Test)解決
ディレクトリ名とファイル名をクラス名と合わせる必要があるらしい!!
以下の記事の最後のほう!!
あーむかついた!
Rails Runnerを使ってみる
- 投稿日:2019-07-10T16:52:12+09:00
Mac にHomebrew を導入する
HomebrewはMacのOSXなか一番人気が集まっているパッケージ管理ツールである。
事前準備:
Homebrewのインストールには、Xcode Command Line Toolsのインストールが必要
もしXcode Command Line Toolsがインストールがインストールされ中たら以下のコマンドでインストールして置きましょxcode-select --install
インストール:
Homebrewは以下のコマンドで直接インストールできます。
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"次に/usr/local/binを$PATH環境変数に追加するのを忘れましょう
$ echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile上記、手順が終わったら、以下のコマンドでHomebrewが正しくインストールされている事を確認しましょう
$ brew doctor
使用方法:
あるパッケージをインストールしたい場合は簡単に以下ようにコマンドを叩きます。
$ brew install <package_name>もし、Homebrewのパッケージリストを更新したい場合は
$ brew update
インストールされたパッケージに更新が必要なパッケージがあるかないか確認するには
$ brew outdated
パッケージ名を指定して更新したい場合は
$ brew upgrade <package_name>
キャッシュされた古いパッケージをクリアするには
$ brew cleanup
インストールされたパッケージのリストとパージョンを確認するには
$ brew list --versions以上、Homebrewのインストール方法と簡単な運用方法を纏めました。
- 投稿日:2019-07-10T14:59:15+09:00
rbenvで環境切り替えたとき用にRubyのrequire一覧を出すTool
TL;DR (長い三行で)
・
rbenv
でRubyのVersionを入れ替えたときに,Gem
が入ってなくてrequire xxx
でエラーが出る
・エラー出るたびにgem install xxx
するのしんどい
・いまあるrequire xxx
を全部リストアップするToolつくるでできたもの
gen_require_lines.rb#! /usr/bin/env ruby #! ruby # ENCODING: UTF-8 #### SEARCH ALL .RB FILES UNDER PWD def get_rb_files(root_dir) rb_files = [] Dir.entries(root_dir).each { |entry| next if entry.start_with?('.') entry_full_path = "#{root_dir}/#{entry}" case File.ftype(entry_full_path) when 'directory' sub_results = get_rb_files(entry_full_path) rb_files += sub_results when 'file' if entry.end_with?('.rb') rb_files << entry_full_path end else # NOP. end } return rb_files end total_rb_files = get_rb_files(Dir.pwd) total_rb_files.sort! #### PARSE EACH .RB require_lines = [] total_rb_files.each { |rb| File.open(rb) { |file| file.each_line { |line| line.force_encoding('UTF-8') line.chomp! line.scrub! line.strip! if !line.match(/^require\s/).nil? require_lines << line end } } } require_lines.uniq! require_lines.sort! #### OUTPUT require_lines.each { |line| puts line }まとめると
こんなTool作るハメになる前に,外部依存関係はちゃんと管理しましょう.
---///
- 投稿日:2019-07-10T14:32:02+09:00
【Rails】sendを使ってメタプロっぽい書き方をしたので記しておく
タイトル通り、sendメソッドを使ってメタプロっぽい書き方をやってみたので書き残しておく。
説明
deviseで
client
とcreator
という2つのモデルを用意している。
それぞれ、nameが登録されているか/されていないかによって、ログイン後の繊維ページが異なるが、
clientとcreator間での法則性は同一である。
↓こんな感じ
name登録済み name未登録 client client_mypage_path edit_client_path(current_client) creator creator_mypage_path edit_creator_path(current_creator) send使ってafter_sign_in_path_for
application_controller.rbclass ApplicationController < ActionController::Base helper_method :current_resource, :current_resource_model, :other_side_model, :registered_name? def current_resource if client_signed_in? current_client elsif creator_signed_in? current_creator end end def current_resource_model return unless current_resource current_resource.class.to_s.downcase end # ログイン後に遷移するpathを設定 def after_sign_in_path_for(resource) return unless current_resource resource_mypage_path = send(current_resource_model + "_mypage_path") edit_resource_path = send("edit_" + current_resource_model + "_path", current_resource) registered_name? ? resource_mypage_path : edit_resource_path end def registered_name? current_resource&.name.present? endこのように、複数のdeviseモデルでの法則的なコードを1つにまとめて記述する時に役に立ちそう。
- 投稿日:2019-07-10T13:13:05+09:00
ハッシュの様々な記述法
今回は、3つのハッシュの記述法を紹介する。
1.ハッシュロケットのみの記述法
hash1 = { "key" => "value"}2.ハッシュロケットおよびシンボルの記述法
hash2 = { :key => "value"}3.シンボルのみの記述法
hash3 = { key: "value"}※keyと:(コロン)の間にスペースがあると、構文エラーになる。
最近では、ハッシュロケットを用いた記述法がなされることは少なく、シンボルのみの記述法が主流になっているみたいである(あくまで、自分の感想の範囲内)。
<参考記事>
・http://mikanmarusan.hatenablog.com/entry/2017/12/29/005632
・https://qiita.com/yukimura1227/items/8c972efb27667dfac5cd
・https://qiita.com/YusukeHigaki/items/18db85aa9cba3cb42569
- 投稿日:2019-07-10T13:13:05+09:00
ハッシュの2つの記述法
今回は、2つのハッシュの記述法を紹介する。
1.ハッシュロケットおよびシンボルの記述法
hash2 = { :key => "value"}2.シンボルのみの記述法
hash3 = { key: "value"}※keyと:(コロン)の間にスペースがあると、構文エラーになる。
最近では、ハッシュロケットを用いた記述法がなされることは少なく、シンボルのみの記述法が主流になっているみたいである(あくまで、自分の感想の範囲内)。
ちなみに、ハッシュとしては別物ではあるが、以下のようにハッシュと似たような書き方がある。
文字列としての書述法
hash1 = { "key" => "value"}<参考記事>
・http://mikanmarusan.hatenablog.com/entry/2017/12/29/005632
・https://qiita.com/yukimura1227/items/8c972efb27667dfac5cd
・https://qiita.com/YusukeHigaki/items/18db85aa9cba3cb42569
- 投稿日:2019-07-10T13:11:49+09:00
あなたはRailsチュートリアルで一体なにを学んだというのか【4章】
注意:プログラミング歴29日の初心者が書いています
注意:間違っていたら優しく教えてください(喜びます)
「Ruby on Rails チュートリアル実例を使ってRailsを学ぼう」
https://railstutorial.jp/素晴らしいチュートリアルに感謝します。
4.1.1 組み込みヘルパー
組み込み関数ってなんですか
組み込み関数とは、プログラミング言語がもともと用意してくれている関数のことです。
ビルトイン関数とも言います。ヘルパーってなんですか
viewで使える関数のことをrailsではヘルパーと呼んでいます。
つまり、
「組み込みヘルパー」とは
「railsがもともと用意してくれている」
「viewで使える関数」
のことです。
4.1.2 カスタムヘルパー
カスタムヘルパーってなんですか
「自分でカスタムした(自分で作る)」
「viewで使える関数」
ということになります。
リスト 4.2: full_titleヘルパーを定義する
「Home」ページにアクセスした際に、
Home | Ruby on Rails Tutorial Sample App
ではなく、Ruby on Rails Tutorial Sample App
のみを表示させたい。
しかし、現状のコードのまま実装を進めると、|(縦棒)
が残ってしまいます。「full_title」関数(ヘルパー)を作って、
|(縦棒)
が残らないようにしましょう。viewで使いたい関数はhelperディレクトリ内のファイルに記述する
これです。ここで言いたいのは多分これです。
「viewで使いたい関数はhelperディレクトリ内のファイルに記述すること」ヘルパーの中身
module ApplicationHelper # ページごとの完全なタイトルを返します。 def full_title(page_title = '') #1 base_title = "Ruby on Rails Tutorial Sample App" #2 if page_title.empty? #3 base_title #4 else page_title + " | " + base_title #5 end end end#1: full_title関数の定義・引数
page_title = ''
は、『引数としてpage_title
をとる。引数の指定がない場合は' '
を引数とする』という意味です。#2: 変数
base_title
に"Ruby on Rails Tutorial Sample App"
を代入。#3:
page_title
に対して.empty?
メソッドを用いて、変数内に値が存在するかどうかで条件分岐させます。#4:
.empty?
メソッドは、変数が空ならTrue
を返します。page_title
が空のとき、base_titile
のみを返します。
(ちなみに、Rubyではメソッドがtrueまたはfalseを返す場合、メソッド名に?がついています。)#5: 変数内に値が存在する場合、
page_title
と|(縦棒)
とbase_title
を返します。
application_helper.rb
に書き込まれた上記の内容は、railsの力によって、自動的にapplication.html.erb
で使用可能になります。apprication.html.erbの中身
<title><%= full_title(yield(:title)) %></title>タイトルタグのコードです。
ヘルパーで定義した、「full_title」関数を呼び出しています。引数には、yieldメソッドでページごとにprovideで設定してあるタイトルを呼び出しています。
Homeページから「Home | 」を取り除く
まずはテストから作り初めて、それからテストを通す実装をします。
test "should get home" do get static_pages_home_url assert_response :success assert_select "title", "Ruby on Rails Tutorial Sample App"#←ココ endhome_urlのgetリクエストに対して、
titleは"Ruby on Rails Tutorial Sample App"
を表示
というテストです。
rails test
すると当然失敗します。
なぜなら、home.html.erb
でprovide
メソッドがタイトルとして"Home"を指定しているからです。テストを通すためには、
home.html.erb
から、provide
メソッドの行を取り除きます。4.3.2 ブロック
ブロックは、メソッドの引数として渡すことのできる処理のかたまりです。
{}波括弧
やdo ... end
の部分がブロックです。test "should get home" do get static_pages_home_url assert_response :success assert_select "title", "Ruby on Rails Tutorial Sample App" endテスト文も、じつは
test
メソッドが、引数としてブロックをとっています。
do ... end
で挟まれた処理がtest
メソッドの引数になっています。4.4.5 ユーザークラス
class User attr_accessor :name, :email #アクセサメソッド def initialize(attributes = {}) #initializeメソッド @name = attributes[:name] @email = attributes[:email] end def formatted_email #インスタンスメソッドの定義 "#{@name} <#{@email}>" end end#アクセサメソッド
インスタンス変数に、クラス外からアクセスできるようになります。#initializeメソッド
User.newを実行すると自動的に呼び出されるメソッドです。
.newと同時に実行されます。#インスタンスメソッドの定義
メソッドを呼び出すことで、
"ユーザー名 <メールアドレス>"という文字列を返すメソッドです。
特に意味はないです。user = User.new(name: "Michael Hartl", email: "mhartl@example.com")上記のように使えます。
- 投稿日:2019-07-10T12:49:15+09:00
[Rails]既存のデータベースにRailsで接続してActiveRecordでレコードを抽出する方法
やりたいこと
[Rails]gem"whenever"を使って定期的にタスクを実行するの続きです
今回は その2:既存のデータベースにRailsで接続してActiveRecordでレコードを抽出する をやりますconfig/database.ymlの中身を変更
development: adapter: mysql2 database: データベース名 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: ユーザ名 password: パスワード host: ホスト port: ポート番号既存のデータベースのスキーマ情報を新規Railsプロジェクトにコピーする
参考記事
Rails - schema.rb(既存DBを使ったアプリ作成)
既存DBを使ってRails以下のコマンドでスキーマ情報がdb/schema.rbに書き込まれる
rake environment -t RAILS_ENV=development db:schema:dump空のマイグレーションファイルを生成して中身を先ほどコピーしてきたschema.rbに置き換えてマイグレートする
rails g migration create_table 中身を書き換えてから rails db:migrateモデルを生成する
テーブルの数だけ作るらしいです(正直まだ理解できてません)
でも作らないとエラー吐かれるので作りました...
オプション指定するとマイグレーションファイル生成するのを防ぐことができます
rails g model モデル名 --migration false
ここまで設定したらActiveRecord使えるようになりました!
lib/tasks/testsql.rb
namespace :testsql do desc "sqlの定期送信" task sql: :environment do require 'json' result = TalkHistory.where(call_status: 'skyway_ringing').where(call_duration: nil).where('talked_at>?',Time.zone.now - 1.days).count("id") result_hash = {"count"=> result} result_json = JSON.generate(result_hash) File.open("test2.json","w") do |file| file.puts result_json end end end
- 投稿日:2019-07-10T12:24:03+09:00
Rails6 のちょい足しな新機能を試す50(scaffold 編)
はじめに
Rails 6 に追加されそうな新機能を試す第50段。 今回は、
scaffold
編です。
Rails 6 では、 belongs_to な関係のあるモデルがあるアプリを scaffold で作った場合に、 belongs_to で指定される親モデルの表示のされ方が変わりました。
...ってなんだか良くわかりませんね。実際にやってみた方がわかりやすいです。
Ruby 2.6.3, Rails 6.0.0.rc1, Rails 5.2.3 で確認しました。Rails 6.0.0.rc1 は
gem install rails --prerelease
でインストールできます。$ rails --version Rails 6.0.0.rc1rails プロジェクトを作る
$ rails new rails6_0_0rc1 $ cd rails6_0_0rc1scaffold を使う
scaffold で Author と Book の CRUD を作成します。Book は、 Author に属します。
$ bin/rails g scaffold Author name $ bin/rails g scaffold Book title author:referencesseed データを作る
Author と Book のデータを1つずつ作成します。
db/seeds.rbauthor = Author.create(name: 'Dave Thomas') Book.create(title: 'Programming Ruby', author: author)データベースを作る
データベースを作って seed データを登録します。
$ bin/rails db:create db:migrate db:seed
rails server を実行して Book のデータを表示する
rails server を実行します。
$ bin/rails s
http://localhost:3000/books と http://localhost:3000/books/1 で一覧画面と詳細画面を表示します。
Rails 5 では
一覧画面でも詳細画面でも、Author はAuthorオブジェクト(
Author#to_s
)を表示します。一覧画面
詳細画面
Rails 6 では
一覧画面でも詳細画面でも、Author は ID (
Author#id
) の 1 を表示します。一覧画面
詳細画面
試したソース
試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try050_scaffold参考情報
- 投稿日:2019-07-10T12:13:58+09:00
[Rails]gem"whenever"を使って定期的にタスクを実行する
やりたいこと
その1:定期的にSQLを発行して返ってきたデータをjson形式でファイル出力する
その2:既存のDBにRailsで接続してActiveRecordでレコードを抽出する
その3:AWSのS3ストレージにjsonファイルをアップロードする
この記事ではその1だけgem"whenever"を利用した定刻処理の実装
この記事の通りにやりました。記事書いてくれた人ありがとうございます。
参考記事
[初学者]whenever を使って定期的にバッチ処理を行う(公開設定編)コードの全体像
namespace :testsql do desc "sqlの定期送信" task sql: :environment do #SQLの接続 require "mysql2" require 'json' client = Mysql2::Client.new(host: '******', username: ENV["DB_USERNAME"], password: '******', database: ENV["DATABASE"]) result = client.query("select count(id) from talk_histories where call_status = 'skyway_ringing' and call_duration is NULL and talked_at > (now() - interval 1 day)") puts result #=> <Mysql::Result>オブジェクトが返ってくる result.each do |r| puts r #=> {"count(id)"=>85} puts r["count(id)"] #=> 85 $count = {count: r["count(id)"]} #グローバル変数$countにハッシュ形式で格納 end #ファイル作成 File.open("test.json","w") do |text| text.puts $count end #jsonファイルのアップロード require 'aws-sdk' s3 = Aws::S3::Resource.new( #S3リソースの作成 :region => 'ap-northeast-1', :access_key_id => '******', :secret_access_key => '******', ) bucket = s3.bucket('testbucket0709') #バケットの作成 bucket.object('test2').upload_file("test2.json") #.objectの引数がキーになる puts bucket.object('test2').exists? #"test2"のキーを持つオブジェクトがバケットにあるか確認 puts bucket.object('test2').get.body.read #オブジェクトの読み込み end end問題:出力したファイルがJSON形式になっていなかった
json形式になっているかどうかの確認はこちらでやりました
JSONLint参考記事
RubyでのJSONの書き込み
RubyでJSONを扱うときに便利な関数まとめ僕はハッシュなら全部JSONなんじゃないのとか思ってましたがよく見ると全然違いますね
ハッシュ
{"json"=>"12345"}
JSON
'{"rails": {"json": "12345"}}'
どうやらRubyのライブラリを使うそうです
JSON.generate(配列)とするとjson形式のファイルができるっぽい
- 投稿日:2019-07-10T11:49:41+09:00
form_tagをform_forに書き換える
初めまして!
Rails初学者が初めてQiitaで書きます!form_forってどうやって書いたらいいの?
アプリを作成する際に苦戦したので備忘録として記事を残しておきます。
form_for基本形<%= form_for (modelobject, option) do |f| %> フォームコントロールの設定 <% end %>これ書いたらformが作成されると思っていましたが、うまくいきません。
まずはビューの部分を記述する
new.html.erb<div class="contents row"> <%= form_for @post do |form| %> //@postにフォームコントロール内で入力する値を入れる// <h5>タイトル</h5> <%= form.text_field :content, placeholder: 'content' %> //ブログのタイトルを入力する為のtext_field <h5>本文</h5> <%= form.text_field :content, placeholder: 'content' %> //ブログの本文を入力する為のtext_filed <%= form.submit "SENT" %> //送信ボタン <% end %> </div>次にcontrollerを編集する
posts_controller.rbclass PostsController < ApplicationController before_action :move_to_index, except: [:index, :show] def new @post = Post.new //新規作成された値は@postに入れる end //~省略~これでform_for内で入力した値は@postに渡されます!
新規作成のフォームは完成したので次は編集する時のフォームの書き方。編集のビュー部分の作成
edit.html.erb<div class="contents row"> <%=form_for @post, url => {action: 'update'} do |form|%> //form_forのupdateアクションを明示する為にaction:を指定 <h5>タイトル</h5> <%= form.text_field :title, placeholder: 'title:最大文字数20文字まで' %> <h5>本文</H5> <%= form_text_field :content. placeholder 'content'%> <%= form.submit "SENT" %> <% end %> </div>次にcontrollerを編集する
posts_controller.rbclass PostsController < ApplicationController before_action :set_post, only: [:edit, :show] //共通のアクションはcallbackする為、before_action内に設定 〜省略〜 def show end def edit end private def set_post @post = Post.find(params[:id]) end def post_params params.require(:post).permit(:content, :title) end end以上でform_forでフォームの新規作成と編集ができるようになりました!
最後に
筆者について
TEXH::EXPERT渋谷校の夜間クラスで4月からRuby・Railsの学習をしています。
記載内容に不備・不足があればご指摘いただけると幸いです。
至らぬ点ばかりですので、改善点がありましたらどんどんご指摘下さい!
- 投稿日:2019-07-10T10:12:27+09:00
#Ruby / #Rails - FactoryBot でエイリアスを呼び出すみたいに、元の定義をコピー・継承して別名を作る
Ruby / # Rails-Copy and inherit the original definition to create an alias, just like calling an alias in FactoryBot
Factoryの中にFactoryを書くだけで良いらしい。こいつは使える!
factory :user do name { 'SomeName' } factory :alice do name { 'Alice' } end factory :bob do name { 'Bob' } end endFactoryBot.create :user FactoryBot.create :alice FactoryBot.create :bobOriginal by Github issue
- 投稿日:2019-07-10T10:00:40+09:00
nested attributes 使用時に毎回新規登録が行われてしまう
概要
accepts_nested_attributes_for を使って、とあるレコードの編集時に、関連レコードの新規作成/更新 を行うようにしたつもりだったのですが、なぜか常に新規登録扱いになってしまい、SQL発行時に Duplicate entry でエラーになる、という事象がおこっていました。
原因は大したことなかったのですが、これにハマったのが2度目だったので自戒のため記事に残しておくことにした次第です。よろしければお付き合いください。
環境
- Ruby 2.5.1
- Rails 5.2.2.1
結論
先に結論を書いておきます。
id
を permit メソッド内で許可していなかったから。 です。ハマるときに限って、意外と原因は大したことなかったりします。
舞台設定
順に説明していきます。まず今回の Model と Controller について記載します。
Model
Parent
が親で、Child
が関連モデルです。名前がいまいちですがご容赦くださいparent.rbclass Parent < ApplicationRecord has_one :child accepts_nested_attributes_for :child, allow_destroy: true endchild.rbclass Child < ApplicationRecord belongs_to :parent self.primary_key = :parent_id endController
問題の原因はここにあります。ここではあえて問題が再現する状態のままにしています。
child_controller.rbclass ChildController def update if @parent.update(child_params) # リダイレクト先は適当に書いたただの例なので気にしないでください redirect_to detail_page_path(@parent) else render :edit end end def child_params params.require(:parent).permit( # parent側もいろいろ指定がありますがここでは省略してます child_attributes: %i[title _destroy] ) end end問題の解消方法
前述コントローラの
child_params
メソッド内を下記のように変更すると解消します。結論で書いたとおりですが、id
を permit メソッド内で許可するキーに追加しています。- child_attributes: %i[title _destroy] + child_attributes: %i[id title _destroy]そもそもこの
id
って?まずはこちらをご覧ください。これは child_controller に対応したビューの一部です。このようなフォームを作成しています。
child.html.erb<%= form_with(model: @parent, local: true) do |form_parent| %> <!-- parent のフォームは省略 --> <%= form_parent.fields_for :child, @parent.child.build do |form_child|%> <%= form_child.text_field :title, placeholder: 'なんか入力してくれ' %> <%end%> <%end%>そして、実際に生成される child 分のフォームは以下のような html になります。
item.html<input placeholder="なんか入力してくれ" type="text" value="" name="parent[child_attributes][title]" id="parent_child_attributes_title"> <input type="hidden" value="2" name="parent[child_attributes][id]" id="parent_child_attributes_id">おや?
parent[child_attributes][id]
という、自分では作成した覚えのない input hidden のフォームが生成されています。これがid
パラメータの正体のようです。value 属性に入っているのはchilds
の主キーであるparent_id
の値でした。どうやらこの値を見て、新規登録か、既存レコードの更新かを区別しているようです。新規登録の際は value に何も入っていません。そのため、コントローラ側の処理で
id
を permit メソッド内で許可しておかないと、常に新規登録として扱われてしまう、ということです。ここで注意が必要なのが、主キーのカラム名は parent_id であるにも関わらず、input タグの name 属性には必ず id という名前が使用される という点です。DBのカラム名でそのまま考えると permit には
parent_id
を書いてしまいがちなんですが、主キーが送信されているパラメータの名前は常にid
という名前であるため間違えないように気をつけましょう。でないと僕の二の舞になります。こんなミスする人は僕だけかもしれませんが参考
余談
とはいえ、Rails はほんとにDB保存系の処理を書くのが楽ですね。そもそも最近の ORM ってみんなこんなかんじなんでしょうか?Laravel の ORM とかどうなんだろう、ということをふと考えました。
- 投稿日:2019-07-10T09:10:01+09:00
Ruby基礎知識
- 投稿日:2019-07-10T09:07:50+09:00
コンフリクトの発生原因について(merge)
rubyでコードを書く時みなさん基本的には作業用ブランチを作成して、主にそこでコード書く。完了したらcommitして、masterブランチにmergeする。
しかし初学者にありがちなmergeをしたら、(master|MERGEING)になってそこからgitコマンドが使えなくなった経験はございませんか??
そんな初学者向けに陥りやすい原因と解決策について一つのやり方(正しいかは別)として参考程度に考えていただけたらなともいます。コンフリクトとは
相反する意見、態度、要求などが存在し、互いに譲らずに緊張状態が生じること。 対立、軋轢。プログラミング(ruby)に関しては主に現場ではgit cloneした時なんかに生じるエラーになるかと思われます。しかし、今回はbranch作成してmasterブランチでのmergeに起きるエラーについてかいていきます。
発生原因
基本的にはコンフリクトは「衝突」のような意味合いもあるので、mergeする際の衝突をイメージできるかと思います。
では、mergeの衝突を具体例を持って説明したいと思います。1、1つのmergeしてないブランチを作成する
git checkout -b Test1
2、ここではREADME.mdファイルでのコンフリクトをさせるための文を書きます
ruby:README.md
'コンフリクト1を作成しました。'
3、保存が終わったらcommitまでしていきます。
git add -A
git commit -m Test1
git checkout master
4、mergeをせずに手順1にもどり同じことをする(TestとREADMEの数だけ変えています)
5、手順3まで終わったら今masterブランチにいる状態だと思います。ここでまず最初にコミットしたTest1をmergeします。
git merge Test1
ruby:README.md
'コンフリクト1を作成しました。'
空白だったとこに無事反映されています。6、では次に2つ目に作ったTest2をmergeします。
git merge Test2
すると次はエラーがでてしまいました。7、ここの文だけでもREADMEファイルに問題があるのは明白なのですが、一応ステータスの方でも確認をしておきましょう。
git status
赤文字で
modified
とかかれファイル名もREADME.md
と書かれてますね。8、次は問題のREADMEファイルをみてみましょう。
先ほど文が2個表示されていますが、なにやらいらないものがついてきちゃってますね。
HEAD ... 最後にmergeしたもの
Test2 ... 2個めにmergeしたものまとめ
このように1つ目のブランチを
merge
せずに2つ目のブランチ作成して作業するとこのように食い違いが起きるわけです。Test2
をmerge
しようとしてもブランチにはコンフリクト1を作成しました。
という文は含まれていないのですから、ここでコンフリクト
という現象が発生します。特に初心者のかたはmergeをうっかり忘れて次のブランチを作成していまい、コンフリクトが発生する(私も何回かやっていました。笑)ので落ち着いてgit log
等も確認しながら作業進めていきましょう!すこしでも初学者のかたの役にたてたらなと思います
また、何か間違っているところ、こうした方がいい等のご意見いただましたらよろしくお願いします。
- 投稿日:2019-07-10T01:03:08+09:00
railsのcontrollerからjavascriptに対して変数を渡す
About
railsからjavascriptに対して変数を渡す方法の一つについて記載しています。
html.erbファイル内にscriptタグでjavascriptを書いた場合に変数を渡せる方法です。Environment
この記事ではmacbook(unix)にインストールしたruby 2.5.1p57, Rails 5.2.3を使用しています。
変数の渡し方
controller内での変数の定義
まずは変数をcontroller内で定義します。
今回は配列を渡してみます。sleeps_controller.rbclass UsersController < ApplicationController def show @user = User.find(params[:id]) @sleeps = @user.sleeps.order('date DESC').includes(:user).limit(14).reverse end endhtml.erbで変数を受け取る
ここからは力技です。参考までにamchartsのスクリプトを拝借しています。
他に良い方法があると思いますので、最終手段くらいに思っていただければと思います。
また、良い方法がある方、コメントいただけると幸いです。show.html.erb<!-- Chart code --> <script> //略 // Add data var sleepings = '<%= @sleeps %>' // 以下略 </script>この様にすることで、javascriptの変数として、文字列を渡すことができます。
ただし、ここで注意しなくてはいけないのが、あくまで javascript側には文字列が渡されるだけ、ということです。そのため、以下の様に文字列を分解して、配列に変換しています。
文字列の[]をそれぞれ置換の要領で削除し、カンマでsplitし、配列化します。show.html.erb<!-- Chart code --> <script> //略 // Add data var sleepings = '<%= @sleeps %>'.replace(/\[/g, "").replace(/\]/g, "").split(','); // 以下略 </script>これでjavascriptにrailsのcontrollerから値を渡す事ができます。
...ゴリ押し感が否めないですが。最後に
ここまでゴリ押し感が強いものを共有するべきか悩みましたが、同じ様な悩みを抱えている方が少しでもいらっしゃれば、その方の助けになるかもと思い書きました。
さらに良い方法がありましたら、是非教えてください!筆者について
TECH::EXPERTにて4月よりruby, railsを学習している未経験エンジニアです。
記載内容に不備・不足があればご指摘いただけると幸いです。
至らぬ点ばかりですので、改善点がありましたらどんどんご指摘下さい!