- 投稿日:2019-07-01T23:51:36+09:00
Python on Djangoで基本的なCRUDとAuthを備えた家計簿を作る
リンク
https://github.com/ItoYo16u/django_crud
自分用メモ+α: 余裕があるときに追記します。
Djangoの構成
Djangoはプロジェクトレベルとアプリケーションレベルの層がある。
プロジェクトの中に家計簿のCRUDを実装したcrudアプリケーション、ユーザー認証機能を実装したaccountsアプリケーションをつくる。
追記したプロジェクト内のアプリケーションはmanage.pyと同じ階層にあるsettings.pyのINSTALLED_APPS内に追記する。
Hello World
$ django-admin startproject <project_name>gitignoreをmanage.pyと同じ階層に追加
.gitignore*.pyc *~ __pycache__ myvenv db.sqlite3 /static .DS_Store$ git init$ python3 manage.py createapp <app_name> $ python3 manage.py migrate $ python3 manage.py createsuperuserpython manage.pyとしている記事もあるが、Syntax errorになるのでpython3 manage.py...としている。
以下を追加
urls.pyfrom app_name import views urlpatterns =[ path('',views.index,name="index"), #.............省略............ #.............省略............. path('app_name/',include('app_name.urls')) ]app_name/urls.pyfrom django.urls import path from . import views app_name='app_name' urlpatterns=[ path('',views.index,name="index"), # nameを指定しておくことでtemplates側から # "{% url 'app_name:name' %}"で呼び出せる。 # railsの場合、controller_name_method_name_pathが自動で設定される。便利。 ]views/index.pydef index(request): return HttpResponse("Hello, world.")$ python3 manage.py runserverGET localhost:8000/基本的なCRUD
Create, Read, Update, Delete機能を作る。
Create
formのレイアウト設定がややめんどくさい。Railsの場合は、formのクラスやスタイルをviews(Djangoのtemplates)で指定できるが、Djangoの場合、forms.pyで設定しないといけないのでbootstrapなどのCSSフレームワークが使いづらい。
Read
views(Railsでいうコントローラ)内のメソッドにパラメタをリクエストと一緒に渡す。
views.pydef show(request,id=None): target= get_object_or_404(TargetModel.objects,pk=id) return render(request,"app_name/show.html",{'rec':rec}) # renderで変数をテンプレートに渡して、htmlをレンダリングして、返す。Djangoはそんなに好きじゃないけど、get_object_or_404()はそこそこ便利
以下はRuby on Railsの場合
hoge_controller.rbdef show @target= TargetModel.find(params[:id]) #request parameterはparams[:params_name]で取得できる #あとは自動で、hoge/show.html.erbがレンダリングされて返される。 # html以外を返す場合などは、renderメソッドを使って明記する end
Update
Delete
Railsはlink_toにmethod: :DELETEを付与できるが、Djangoではできない。HTMLと同様にGETかPOSTしか送れない。
(ライブラリを使えばできるらしい)
DjangoのCRUDについて調べているとDELETEにGETを使っている記事がいくつか見つかるが、なるべくPOSTを使うべき。
※Railsの場合、
=link_to "hoge",foo_bar_path,method: :deleteroutes.rbDELETE 'foo/bar' ,to: 'foo#bar'foo_controller.rbdef bar # 処理内容 endと直感的に書けるが,Djangoの場合はそうはいかないようだ。
基本的なAuth
Djangoにデフォルトで搭載されているUserモデルとAuthを使う。
Ruby on Railsの場合、デフォルトでは認証機能はないのでdeviseというgemを導入して、devise:installなどのコマンドをうったり、ルーティング設定したりしないといけないのでややめんどくさい。
基本のユーザーはfrom django.contrib.auth.models import Userで呼び出せる。
今回は家計簿なのでモデルは
- User has many 家計簿
- 家計簿 belongs to User
の関係にある。
Djangoのデフォルトの認証viewsのメソッドが用意されているが、SignUpだけは用意されていないので、自前で作る必要がある。
sign up用のviewをつくる
アクションを認証済ユーザーに制限する
@login_required #をアクションの直前につける3.リダイレクトを設定する
@login_required #がついている場合,自動でリダイレクト # リダイレクト先はsetting.py LOGOUT_REDIRECT_URL で指定する# 2と3はRuby on Railsの場合こう書ける before_action :authenticate_user! #オプション,only: [:method_name],except: [:method_name],....共通部分のpartial化
header, footerなどの共通部分は、Railsと同じようにpartial化できる。(Djangoの場合、partialというよりも、継承といったほうが正しいが、、、)
PythonAnywhereにデプロイする
- 投稿日:2019-07-01T23:05:49+09:00
【Rails】カラムの合計値を求める!
やりたいこと
保存されているデータの特定のカラムの合計値を出したい!と思いました。
最初考えたのは、①取得したいカラムのモデルをeach文で1件ずつ取得し、そのデータのカラムを一度配列にする
②↑の配列に対してsumメソッドで合計を求めるこれでも全然問題なかったのですが、
sumメソッドの引数で直接カラム名を指定し、合計値を求めることも出来ると知ったのでまとめます!カラムの合計を求める方法①
これは私がもともと考えていたやり方です。
test.rb#booksテーブルのpriceカラムの合計値を求めたい場合 array = [] #空の配列を用意し、 Book.all.each do |book| array << book.price #bookテーブルのレコードを1件ずつ取り出し、priceカラムのデータを配列に入れる end array.sum #ここで合計を求めるカラムの合計を求める方法②
次に、もっと簡単な1行でできるやり方です。
test.rbBook.all.sum(:price)これだけでいけました。
sumメソッドの引数でカラムを指定できるとは知らなかったです!
とても楽ですねまた、さらにオプションを付けることもできます!
興味のある方はぜひこちらのサイトをご参考ください!
http://railsdoc.com/references/sum
- 投稿日:2019-07-01T22:56:11+09:00
GitHub リポジトリの作成方法(ローカル環境)
新規作成したアプリのリポジトリをGitHub上で作る
まずは、アプリの作成(今回はデータベースにポスグレを使用)
$ rails new (アプリ名) -d postgresqlGitHubにアクセス
①new repositoryボタンを押す。
②リポジトリ名を決めて、Create repositoryボタンを押す。
GitHubとローカルをSSH接続
SSHという認証技術を使用して、GitHubとローカルをSSH接続する。
⇨セキュリティの脆弱性の観点から、一般的には公開鍵認証方式を使用。
(ここで、公開鍵と秘密鍵という概念が出てくるが、ここでは説明は割愛)SSH keyの作成
$ ssh-keygen -t rsa -C "GitHubに登録した自分のメールアドレス"Overwrite (y/n)?の箇所で、yを入力しEnterを押すと、秘密鍵と公開鍵が作成される。
id_rsaというファイルが秘密鍵で、id_rsa.pubが公開鍵。公開鍵の登録とGitHubとの接続確認
公開鍵をGitHubに登録する。
catコマンドを使用するとファイルの中身が確認できるので…$ cat ~/.ssh/id_rsa.pub上記コマンドを実行すると、ssh-rsaから始まり、自分のメールアドレスで終わる長い文字の羅列が表示される。「ssh-rsa」からメールアドレスの末尾までをすべてコピー。
GitHub上に公開鍵を置く
①ヘッダ右上の自分の画像をクリックして、settingをクリック。
②SSH and GPG keysをクリックし、さらにNew SSH Keyをクリック。
③keyのところにコピーした公開鍵の中身を貼り付ける。
GitHubとの接続が正常にできているか確認
# 接続確認コマンド $ ssh -T git@github.com# 接続結果 Hi (GitHubの登録名)! You've successfully authenticated, but GitHub does not provide shell access.このように表示されたら、基本的には接続成功!!!
GitHubのリポジトリにソースコードを送信する
GitHubリポジトリの送り先SSHプロトコルURLを取得
ローカル上で、送り先のSSHプロトコルURLをGitHubからコピー。
(SSHプロトコルURLは、git@から始まる。
httpsから始まるURLは、パスワード認証方式でアクセスすることになる。)GitHubのリポジトリを登録する
ローカル上で、GitHubリポジトリの送り先SSHを登録する。
⇨git remote addコマンドを使用。$ git remote add origin(=省略名) (コピーしたSSHプロトコルURL)$ git remote -v # 送り先SSHの確認例 origin git@github.com:〜 (fetch) origin git@github.com:〜 (push)git pushコマンドの利用
登録したリモートリポジトリ(GitHubリポジトリ)に、ソースコードを送信する。
$ git push origin(=省略名) ブランチ名⬇︎こうするとmasterブランチへコードが送信される。
$ git push origin master…以上が、ローカル環境下で書いたソースコードを、作成したリポジトリに送信する流れ
- 投稿日:2019-07-01T22:56:11+09:00
GitHub リポジトリの作成方法
新規作成したアプリのリポジトリをGitHub上で作る
まずは、アプリの作成(今回はデータベースにポスグレを使用)
$ rails new (アプリ名) -d postgresqlGitHubにアクセス
①new repositoryボタンを押す。
②リポジトリ名を決めて、Create repositoryボタンを押す。
GitHubとローカルをSSH接続
SSHという認証技術を使用して、GitHubとローカルをSSH接続する。
⇨セキュリティの脆弱性の観点から、一般的には公開鍵認証方式を使用。
(ここで、公開鍵と秘密鍵という概念が出てくるが、ここでは説明は割愛)SSH keyの作成
$ ssh-keygen -t rsa -C "GitHubに登録した自分のメールアドレス"Overwrite (y/n)?の箇所で、yを入力しEnterを押すと、秘密鍵と公開鍵が作成される。
id_rsaというファイルが秘密鍵で、id_rsa.pubが公開鍵。公開鍵の登録とGitHubとの接続確認
公開鍵をGitHubに登録する。
catコマンドを使用するとファイルの中身が確認できるので…$ cat ~/.ssh/id_rsa.pub上記コマンドを実行すると、ssh-rsaから始まり、自分のメールアドレスで終わる長い文字の羅列が表示される。「ssh-rsa」からメールアドレスの末尾までをすべてコピー。
GitHub上に公開鍵を置く
①ヘッダ右上の自分の画像をクリックして、settingをクリック。
②SSH and GPG keysをクリックし、さらにNew SSH Keyをクリック。
③keyのところにコピーした公開鍵の中身を貼り付ける。
GitHubとの接続が正常にできているか確認
# 接続確認コマンド $ ssh -T git@github.com# 接続結果 Hi (GitHubの登録名)! You've successfully authenticated, but GitHub does not provide shell access.このように表示されたら、基本的には接続成功!!!
GitHubのリポジトリにソースコードを送信する
GitHubリポジトリの送り先SSHプロトコルURLを取得
ローカル上で、送り先のSSHプロトコルURLをGitHubからコピー。
(SSHプロトコルURLは、git@から始まる。
httpsから始まるURLは、パスワード認証方式でアクセスすることになる。)GitHubのリポジトリを登録する
ローカル上で、GitHubリポジトリの送り先SSHを登録する。
⇨git remote addコマンドを使用。$ git remote add origin(=省略名) (コピーしたSSHプロトコルURL)$ git remote -v # 送り先SSHの確認例 origin git@github.com:〜 (fetch) origin git@github.com:〜 (push)git pushコマンドの利用
登録したリモートリポジトリ(GitHubリポジトリ)に、ソースコードを送信する。
$ git push origin(=省略名) ブランチ名⬇︎こうするとmasterブランチへコードが送信される。
$ git push origin master…以上が、ローカル環境下で書いたソースコードを、作成したリポジトリに送信する流れ
- 投稿日:2019-07-01T22:31:11+09:00
activerecordを使って簡単なコマンドラインアプリケーションを作ってみた
目的とやったこと
rubyとActiveRecordの勉強のために、簡単なコマンドラインベースの「todo管理アプリケーション」を作成した。
開発環境詳細
言語:ruby2.5.3
DB:sqlite3
なお、当然ながらDBアクセスにActiveRecordを利用している。動作している様子
※念のため言っておくと、Cドライブ直下で実行しているのは私のユーザ名を晒したくないからで、Qiita投稿のためだけにそうしています。仕様概要
よくあるタスク管理アプリをコマンドラインで実現している。
CRUDを一通り実装しており、ユーザインタフェースはキーボード入力のみ。
DBはsqliteで実現しており、テーブルは一つだけ(tasksテーブル)。項目は以下の通り
id・・・タスクを一位に定めるための整数値。自動採番かつuniqueである。
name・・・タスクの名前
content・・・タスクの詳細
status・・・タスクの状態。アプリ的には未着手、着手中、完了の3つがあり、それぞれ整数値としている。
なお、updateについて、何も入力をしない場合は現状の項目のままである。(一応工夫しているアピール)ソースコード
相変わらずのクソコードではあるが以下を参照のこと
https://github.com/gitk47320/todoapp
コマンドラインベースとはいえMVCを意識しています。データ操作、ユーザインタフェースは分離している。特にControllerなんて完全にrails意識しているし。。。今後やっていきたいこと
・バリデーションの実装
・タスクアラート機能(遅延気味のタスクをアラートするとか)
・全体的にリファクタリングしたい。view側の実装をmodel側にもう少し持っていけないかなーとは思っている。
- 投稿日:2019-07-01T21:29:07+09:00
Ruby on railsとは?
Railsの事前カリキュラム
どんな記事?
ruby on railsとはなんなのか?ということ自分の中でアウトプットするための記事です、どうか暖かく見守ってください
ruby on railsとは?
ruby on railsは簡単にいうとWebアプリケーション開発を開発するためのフレームワークです。
ここではそもそもフレームワークが何なのかとrailsで使われているコーディングをするシステム(MVCモデル)、rubyとの違いを勉強していきます。フレームワーク
フレームワークとは、Webアプリケーションを機能させるために必要な共通部分を予め用意するものになります。
アプリケーションの開発者は独自に必要なHTML/CSSやRubyの記述に時間を割くことができるので、開発効率が向上します。MVCモデル
Railsではユーザーからのリクエスト->ビュー->コントローラー→モデルの順番に処理が行われます。
このようにモデル(model)とビュー(view)とコントローラー(controller)を使用して処理を行なうシステムをそれぞれの頭文字を取ってMVCモデルと呼ばれています。
以下の図に処理の流れを簡単にまとめました。
rubyとruby on railsの違い
よく間違えられるのですがRuby on Railsはプログラミング言語ではないです。
プログラミング言語は、前テキストで学んでいただいたと思うのですが他にはpythonやJava,Cなどがありましてその名の通りプログラムを実装・実行するための言語です。
例えば、前テキストでRubyを使い足し算や掛け算などの計算、条件に合わせたプログラムの実行、配列作成などを行なったと思います。
一方でフレームワークであるRailsは足し算などをすることはできません。ruby on railsでできること
webアプリケーション開発
インターネット上に公開されているWebサイトはRuby, Ruby on Railsを使って作ることが可能です。
RubyとRuby on Railsを使ってWebサイトを作るメリットはRuby on Railsというフレームワークによる開発スピードです。
Ruby on Railsは非常によく出来たフレームワークで、Webアプリケーションの開発をするために最適化されたツールになります。ここではRuby, Ruby on Railsで開発されているwebサービスをいくつか紹介します。
クックパッド
引用元:クックパッド https://cookpad.com/マネーフォワード
引用元:マネーフォワード https://moneyforward.com/Airbnb
引用元:Airbnb https://www.airbnb.jp/スマートフォンアプリ開発
iOSアプリの開発はobject-cやswift、Androidアプリの開発はJavaやKotlinが一般的です。
しかしRubyでも「RUBYMOTION」(http://www.rubymotion.com/jp/)
というソフトを使うことにより、AndroidアプリやiOSアプリを開発することが可能になります。ruby on railsの特徴
初心者に優しい
ruby on railsが初心者に優しい理由は主に2つあります
1つはシンプルにコーディングできることです。
Railsはコードが短く、簡単な書き方ができます。
それによりコーディング量が少なくなり、短く速い開発を行うことができるメリットがあります。
また次に説明するDRYの原則により、同じコードを何度も繰り返して使うことなく、規約に従った開発を行うことにより自分で設定を行うことなくコーディングを行えます。
これはコードを読んだり書いたりすることの慣れていない初学者には大きなメリットになります。2つ目はrubyが日本発祥の言語だということです。
これにより日本語の情報がオンラインで豊富に手に入ります。
また、コミュニティが活発で初心者でも非常に学びやすい環境が整っています。
例えばruby on railsを使ってオリジナルのアプリケーションを作っている中で遭遇したことのない様なエラーが出たとしても
そのエラーに遭遇している人をオンライン上で見つけることが簡単なので素早くエラーを解決しアプリケーション開発を行うことができます。DRY (Don’t Repeat Yourself)原則
Ruby on Railsには、「Don’t Repeat Yourself(繰り返しを避けよ)」というDRY原則という原則があります。
DRY原則とは、自分でやった事を2度繰り返さないという意味です。同じことをソースコードやファイルの中で何度も記述すると、アプリケーションの仕様変更などがあった時に、一部を変更し忘れてしまう可能性があります。
少しイメージがつきづらいと思うので例を出して説明していきたいと思います。
例えば今ここで今hour時です #hourは変数で中身は数字ですという文字列を100回出力したいとします、みなさんだったらどのようにコードを書くでしょうか?
まさかputsメソッドを使って100回出力しないですよね、基本的にはwhileやfor文を使って繰り返しをさせます。
ではなぜputsメソッドを使って100回出力させない方がいいのでしょうか?
例えば上記の文字列を今hour時minutes分です #minutesは変数で中身は数字ですに変更したいとしましょう、繰り返し構文を使っていないコードを変更するとしたら100回も変更を加えなければなりません。
ただ繰り返しの構文を使っているとしたらその中の文字列1行を変更するだけですみます。
このようにRuby on Railsでは、DRY原則を意識して開発することで、効率の良いアプリケーションを作成することができます。直感的にデータベースを操作することができる
そもそもデータベースとは?
データベースとは一定の形式で整理されたデータの集まりです、現実世界にあるデータベースの例を出すとタウンページなどがわかりやすいと思います。
タウンページは基本的に場所名+電話番号が整理された形でずっと並んでいますよね。
コンピューターの中にもタウンページのようにデータが整理され集合がありましてそれをデータベースと言います。
一般的にデータベースを扱う場合、データベース言語「SQL」を書く必要があります。
SQL言語とはデータベースを操作するための言語です。
例えばTwitterなどを思い浮かべて見てください、Twitterにログインが成功した時には自分のユーザー情報が表示されますよね。
これはユーザーの情報が入っているデータベースに対してSQL言語を書くことによってユーザー情報を表示することができています。ではこれを直感的に操作できるとはどういうことか
例えば、データベースのproductsテーブルからプロダクトIDが1のデータを取得する場合、SQLを使うと以下のように書かなければいけません。SELECT * FROM products WHERE id = 1しかしRailsアプリケーションでデータベースを扱う場合は、SQLを書く必要がなく
@product = Product.find(1)という1行を記述するだけで、データを取得することができます。
これから学習していくテキストの中でもデータベースを扱う場面が多々あると思うのですが
ruby on railsを使っていることで上記の様に直感的にデータベースを扱うことができるようになります。
- 投稿日:2019-07-01T18:47:37+09:00
今日学んだ事(自分用)
7/1(月)
●UI(ユーザーインターフェース)
・ユーザーがPCとやりとりする際の入力や表示方法などの仕組み
●UX(ユーザーエクスペリエンス)
・サービスによってユーザーが得られる体験
───────
●アジャイル開発
・ソフトウェア開発のプロジェクトの進め方。短期間で開発を見直す手法。
●erb記法
・HTMLにRubyスクリプトを埋め込む
●スクリプト
・プログラムの流れ
1.プログラミング(人間の言葉でコンピュターへの命令を記述する)
2.コンパイル(1で書いた内容をPCがわかる言葉に翻訳する)
3. 2の内容にしたがってPCが仕事する
・スクリプト言語は2のコンパイルを飛ばし
プログラミング⇨PCが仕事する流れ●eachメソッド
・要素を1つずつ取得し出力させる
オブジェクト.each do |変数|例.fruits = ["apple","orange","melon"] fruits.each do |a| puts a end 出力 apple orange melon・このような繰り返しメソッドを、イテレートまたはイテレータという。
●order(順序)メソッド
・DBからデータの取得時にデータを並び変える事ができる
・DESC(降順)
・ASC(昇順)
コードモデル名.order('カラム名 順序')●limitメソッド
・データをいくつ取得するか指定するメソッド
コードモデル名.limit('取得件数')●orderメソッドとlimitメソッドを一緒に使う時
モデル名.order('カラム名 順序').limit(取得件数)●find(見つける)メソッド
・引数に指定したidをもつ情報を1件だけ取得する
・作品の個別ページの移行の時などに使う例.User.find(1)●rake routesコマンド
・HTPPアクションの一覧を見る事ができる
・リクエスト、パスに対してのコントローラ、アクション名が確認できるターミナル.rake routes以上
- 投稿日:2019-07-01T17:44:46+09:00
Rubyのモジュールの用途について
Rubyのモジュールの用途(4つ)
①モジュールのミックスインincludeもしくはextend,prependできる(異なるモデルで共通したメソッドを使用するときなど)
- includeとextendの違いが分からないときはこちら
- prependとはなんぞや
- 同名のメソッドがあったときに、ミックスインしたクラスよりも先にモジュールのメソッドを呼ぶ
②モジュールを利用した名前空間の作成(異なるモデルで同じ名前のモデルを作成するとき)
Class::instance.new(implement, 0)③関数や定数を提供するモジュールの作成
- 何気なくターミナルで"puts"を叩けるのはkernelというmoduleのおかげ
- ancestorsメソッドを使えばクラスやモジュールがどの順番で探索されるか確認できる。
④状態を保持するモジュールの作成
- モデルにデータを保持する必要がなければモジュールにしておくことができる。
- 下記記述が必要になってくるため注意。
model.rbattr_accessor :implementRailsのmodelのconcernは?
- Railsのconcernは異なるモデルの中でも同じメソッドやスコープを使用するときに活用できる。
- 投稿日:2019-07-01T17:44:46+09:00
Rubyのモジュールの用途について(学習メモ)
Rubyのモジュールの用途(主に4つ)
①モジュールのミックスインincludeもしくはextend,prependできる(異なるモデルで共通したメソッドを使用するときなど)
- includeとextendの違いが分からないときはこちら(参考)
- prependとはなんぞや
- 同名のメソッドがあったときに、ミックスインしたクラスよりも先にモジュールのメソッドを呼ぶ
- 既存メソッドの置き換え
②モジュールを利用した名前空間の作成(異なるモデルで同じ名前のメソッドを作成するとき)
Class::instance.new(implement, 0)③関数や定数を提供するモジュールの作成
- 何気なくターミナルで"puts"を叩けるのはkernelというmoduleのおかげ
- ancestorsメソッドを使えばクラスやモジュールがどの順番で探索されるか確認できる。
④状態を保持するモジュールの作成
- モデルにデータを保持する必要がなければモジュールにしておくことができる。
- 下記記述が必要になってくるため注意。
model.rbattr_accessor :implementRailsのmodelのconcernは?
- Railsのconcern(参考)は異なるモデルの中でも同じメソッドやスコープを使用するときに活用できる。
refinementsについて
メソッドの有効範囲(スコープ)を指定できる。
model.rbmodule Hoge refine Class do def method hogehoge end end end class Model using Hoge ・・・省略・・・ def refinement_method #ここの範囲だけメソッドが有効となる。 @~~~.method end end
- 投稿日:2019-07-01T17:21:17+09:00
enum_helpについて
はじめに
enumをしようする中でenum_helpというgemを使用したためenum_helpについてまとめる。
enumとは
enum_helpの説明の前にenumについてまとめたいと思います。
enumは数字を何かしらの値と紐付けているようなデータの管理をしている場合に有効なものとなります。class ShippingBurden < ApplicationRecord has_many :items enum name: [:select_shipping_burden, :postage_included, :freight_collect] endこのようにmodel内でenumを定義することでf.selectなどでhamlにoptionを記述しなくても数字で値を表示できるようになります。
しかし、このままでは表示される値が英語表記のまま表示されてしまいます。
そんな時に英語を日本語表記に変える時に必要となるのがenum_helpです。仕様方法
まずはじめに、gemのenum_helpをgemfileに記述します。
gem 'enum_help'そして、bundle install
次に、config直下にja.ymlというファイルを作成し、そこに日本語表記の記述をします。
ja: enums: shipping_burden: name: postage_included: '送料込み(出品者負担)' freight_collect: '着払い(購入者負担)'最後にaplication.rbにja.ymlを適応させる記述を書きます
config.i18n.default_locale = :jaこれで日本語表記で表示させることが可能になります。
- 投稿日:2019-07-01T16:56:15+09:00
to_iとto_s
to_iとto_sについて
どっちがどっちか分からなくなることが多いので、まとめます!
*to_i・・・iの意味はinteger(整数)
*to_s・・・sの意味はstring(文字列)使い分け方法
それぞれの使い方について、詳しくみていきます。
number1 = 10 #数値 number2 = "15" #文字上記を利用してそれぞれのメソッドを利用していきます。
to_iメソッド
文字列オブジェクトに対してto_iメソッドを使うと、その文字列を数値オブジェクトに変換することができる!
つまり、puts number1 + 5 #出力結果 15 puts number2 + 5 #エラー #numberyyyを出力させるためにto_iメソッドを使うと puts number2.to_i + 5 #出力結果 20ということになります!
to_sメソッド
数値オブジェクトに対してto_sメソッドを使うと、その数値を文字列オブジェクトに変換することができる!
つまり、puts number1 + "歳の誕生日です" #エラー puts number2 + "歳の誕生日です" #出力結果 15歳の誕生日です #numberxxxを出力させるためにto_sメソッドを使うと puts number1.to_s + "歳の誕生日です" #出力結果 10歳の誕生日ですということになります!
まとめ
このto_iはgetsメソッドと共に使われることが多いですね。
どちらも似ていて間違いやすいので気をつけて使っていきたいと思います!
- 投稿日:2019-07-01T14:12:41+09:00
active storage で単数から複数にした時に気をつけるべきポイント
N+1 問題を解決するためのスコープを複数形にする
.with_attached_image .with_attached_images受け取るパラメータを配列にする
params.require(:reports).permit(:content, :image) params.require(:reports).permit(:content, images: [])アソシエーションを複数形にする
has_one_attached :image has_many_attached :imagesバリデーションを複数形にする
こちらのバリデーションは下記のgemを使用した例です
activestorage-validator
validates :image, blob: { content_type: %w(image/png image/jpg image/jpeg) } validates :images, blob: { content_type: %w(image/png image/jpg image/jpeg) }番外編
Active Interaction で静的型付けをする場合、string ではなく array にする
デフォルトが nil だとエラーになるので注意してください
string :image, default: nil array :images, default: []
- 投稿日:2019-07-01T14:00:51+09:00
記事を投稿・詳細表示・一覧表示・編集・削除するやり方について
環境
OS:MacOS Mojave 10.14.15
IDE:Cloud9
ruby:2.6.3
Rails:5.0.7.2準備
routing作成
まずはルーティングを準備していきます。
routes.rbresources :aritcles正しく反映されているか、rails routesコマンドで確認してみましょう。
console$ rails routes Prefix Verb URI Pattern Controller#Action articles GET /articles(.:format) articles#index POST /articles(.:format) articles#create new_article GET /articles/new(.:format) articles#new edit_article GET /articles/:id/edit(.:format) articles#edit article GET /articles/:id(.:format) articles#show PATCH /articles/:id(.:format) articles#update PUT /articles/:id(.:format) articles#update DELETE /articles/:id(.:format) articles#destroy正しく反映されていますね。
しかし、この状態でリクエストを送ろうとすると以下の画像のようにルーティングエラーが発生します。
このエラーの原因は「リクエストを処理するためのコントローラーがないため」です。
なので、次はarticlesコントローラーを作成します。articlesコントローラーの作成
以下のコマンドでarticlesコントローラーを作成します。
console$ rails g controller articles Running via Spring preloader in process 9066 create app/controllers/articles_controller.rb invoke erb create app/views/articles invoke test_unit create test/controllers/articles_controller_test.rb invoke helper create app/helpers/articles_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/articles.coffee invoke scss create app/assets/stylesheets/articles.scssarticlesコントローラーが作成されました。
しかし、このままではarticlesコントローラーに対するアクションが作成されていないので、URLにリクエストを送っても、Unknow actionエラーが返されてしまいます。
なので、次はactionを指定します。(一旦、newアクションだけを指定していきます。)/training/app/controllers/articles_controller.rbclass ArticlesController < ApplicationController def new end end
/articles/new
でアクセスしてみます。
すると、今度は以下のようなエラーが発生します。
ArticlesController#missing a template
はarticlesコントローラーのnewアクションに対応するテンプレート、つまりビューがないために起こるエラーです。なので、今度は対応するviewを作成します。
console$ touch app/views/articles/new.html.erbエラーは解消されたと思いますが、入力されたデータを送信して管理する場合は、モデルを作成してDBとやり取りする必要が生じてくるので、Articleモデルを作成していきます。
Articleモデルの作成
今回は、articlesテーブルにtitleカラムとcontentカラムを用意したいので以下のコマンドを実行してArticleモデルを作成します。
console$ rails g model Article title:string content:text Running via Spring preloader in process 4656 invoke active_record create db/migrate/20190630012101_create_articles.rb create app/models/article.rb invoke test_unit create test/models/article_test.rb create test/fixtures/articles.yml続いて、出来上がったマイグレーションファイルを実行していきますが、その前に作成したマイグレーションファイルに誤字等ないか確認します。
/training/db/migrate/hogehoge_create_articles.rbclass CreateArticles < ActiveRecord::Migration[5.0] def change create_table :articles do |t| t.string :title t.text :content t.timestamps end end end問題なさそうなことが確認できたので以下のコマンドでマイグレーションを実行していきます。
console$ rails db:migrate == 20190630012101 CreateArticles: migrating =================================== -- create_table(:articles) -> 0.0060s == 20190630012101 CreateArticles: migrated (0.0065s) ==========================articlesテーブルが作成されたことが確認できたので、次からはそれぞれ機能ごとに必要な処理をモデル、コントローラー、ビューに実装していきます。
※ルーティングは既に揃っているので加えて作成する必要はありません。記事を投稿・詳細表示する
articleコントローラーにnew,create,showアクションを追加していきます。
/training/app/controllers/articles_controller.rbclass ArticlesController < ApplicationController def new #空のArticleオブジェクトを生成 @article = Article.new end def create @article = Article.new(article_params) if @article.save redirect_to @article #@articleはarticle_path(@article)と同義 else #エラー時は再度、記事登録画面を表示させる render :new end end def show @article = Article.find(params[:id]) end private #ストロングパラメータでpermitに渡された値以外を受け取らないようにする def article_params params.require(:article).permit(:title,:content) end endnewアクション内で空っぽのArticleクラスのインスタンスを作る理由は、form_forメソッドに空のインスタンス渡された時は、submitした時にcreateアクションが実行されるように設定されているからです。
反対に、空でない場合はupdateアクションが実行されます。まだこれだけだと、showアクションに対応するviewが足りていないのでそれを作ります。
console$ touch app/views/articles/show.html.erb続けてviewも登録した内容が分かるように書いていきます。
/training/app/views/articles/show.html.erb<table> <tbody> <tr> <th>タイトル</th> <td><%= @article.title %></td> </tr> <tr> <th>内容</th> <td><%= @article.content %></td> </tr> </tbody> </table>ここまで作ったら実際に記事登録画面(article/new)でtitleに「hoge」、contentに「hogehoge」と入力して送信ボタンを押してみましょう。
↑こんな感じでDBに登録された値がうまく表示されていないでしょうか?
記事を一覧表示する
articleコントローラーにindexアクションを追加してallメソッドで登録されている値を全て取り出し@articlesに格納します。
/training/app/controllers/articles_controller.rbclass ArticlesController < ApplicationController ・ ・ ・ def index @articles = Article.all end private def article_params params.require(:article).permit(:title,:content) end endindexアクションに対応するviewがないので作成して、登録された値が全て確認できるようにviewを調整します。(次の「記事を編集する」で使用する編集リンクを先に実装しています。したがって、今はエラーが出ても問題ありません)
console$ touch app/views/articles/index.html.erb/training/app/views/articles/index.html.erb<table> <tbody> <tr> <th>タイトル</th> <th>内容</th> </tr> <% @articles.each do |article| %> <tr> <td><%= article.title %></td> <td><%= article.content %></td> <td><%= link_to '編集',edit_article_path(article) %></td> </tr> <% end %> </tbody> </table>適当に記事登録画面で何か追加してみて
/articles
にアクセスするとこれまで作成したデータが一覧で表示されます。記事を編集する
articlesコントローラーにeditアクションとupdateアクションを追加し、それに対応するviewを追加していきます。
/training/app/controllers/articles_controller.rbclass ArticlesController < ApplicationController ・ ・ ・ def edit @article = Article.find(params[:id]) end def update @article = Article.find(params[:id]) if @article.update(article_params) redirect_to @article else render :edit end end ・ ・ ・ private def article_params params.require(:article).permit(:title,:content) end endconsole$ touch app/views/articles/edit.html.erb/training/app/views/articles/edit.html.erb<h1>編集画面</h1> <%= form_for @article do |f| %> <p> <%= f.label :title, "タイトル" %><br> <%= f.text_field :title %> </p> <p> <%= f.label :content, "内容" %><br> <%= f.text_area :content %> </p> <p> <%= f.submit %> </p> <% end %>findメソッドで該当する記事をDBから取り出し、それを@articleに格納して、view(edit.html.erb)のform_forメソッドに渡します。
この時、form_forメソッドに渡されたインスタンス変数には空ではなく値が入っているため、送信ボタンを押下時にはupdateアクションが実行されます。記事を削除する
articlesコントローラーにdestroyアクションを追加します。
/training/app/controllers/articles_controller.rbclass ArticlesController < ApplicationController ・ ・ ・ def destroy @article = Article.find(prams[:id]) if @article.destroy redirect_to articles_path else redirect_to article_path(@article) end end ・ ・ ・ endリンク押下時に削除できるように一覧画面のviewに削除リンクを追加していきます。
<table> <tbody> <tr> <th>タイトル</th> <th>内容</th> </tr> <% @articles.each do |article| %> <tr> <td><%= article.title %></td> <td><%= article.content %></td> <td><%= link_to '編集',edit_article_path(article) %></td> <td><%= link_to '削除',article_path(article), method: :delete,data: {confirm:'削除してもいいですか?'}%></td> </tr> <% end %> </tbody> </table>methodオプションでhttpメソッドをdeleteに指定してあげることで、確認ダイアログのOKボタンが押された時に、destroyアクションが実行されます。
補足
今回は、要点をまとめるために記事を作成したためArticleモデルにバリデーションやリレーションを追加したりや入力箇所(newやedit)の重複部分をパーシャルを使ってまとめたりはしておりません。
なので、その辺りは適宜カスタマイズしていただきますようよろしくお願いします。最後に
誤っている箇所や追記した方が良い点等ございましたら
編集リクエストやコメントの方でご指摘していただけると幸いです。
- 投稿日:2019-07-01T13:32:13+09:00
【Rails 備忘録】デプロイする時に定番で使うコマンド
はじめに
備忘録です。
デプロイで使うコマンド
前提条件として、
AWS EC2環境/var/www/app/
配下でgit cloneさせます。git clone
言わずもがなgit cloneです。
git pull
言わずもがなgit pullです。
bundle install
bundle install --path=vendor/bundle --without development testassets precompile
bundle exec rails assets:precompile RAILS_ENV=stagingmigrate
bundle exec rails db:migrate RAILS_ENV=stagingrails server起動
bundle exec rails s -e staging -drails server停止
ps aux | grep rails (rails s -e staging -d のプロセスidを見つける) kill プロセスidrails コンソール
bundle exec rails c -e stagingちなみに
上記はstaging環境でのコマンドとなります。
production環境の場合、staging
をproduction
に変更すればOK。
- 投稿日:2019-07-01T12:37:30+09:00
Rails6 のちょい足しな新機能を試す43(ActiveRecord Cache編)
はじめに
Rails 6 に追加されそうな新機能を試す第43段。 今回は、
ActiveRecord Cache
編です。
Rails 6 では、has_many
やbelongs_to
などの関連がある model の reload 時の ActiveRecord のキャッシュに関連する動作が修正されています。reload
しているのに、データベースから読み直されず、キャッシュの古い値が取得されてしまう動作がなくなり、一貫性が感じられる動作になっています。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.rc1プロジェクトを作る
$ bin/rails new rails6_0_0rc1 $ cd rails6_0_0rc1モデルを作る
has_many
やbelongs_to
の関係を作るため、 Author, Book, Edition の3つのモデルを作成します。本 (
Book
) には1人の著者 (Author
) がひもづき (belongs_to
)、複数の版 (Edition
) が存在します。$ bin/rails g model Author name $ bin/rails g model Book title author:references $ bin/rails g model Edition name book:references
has_many
を追加する
Author
とBook
にそれぞれhas_many
を追加します。app/models/author.rbclass Author < ApplicationRecord has_many :books, dependent: :destroy endapp/models/book.rbclass Book < ApplicationRecord belongs_to :author has_many :editions, dependent: :destroy enddb:migrate を実行する
一旦、ここで、 db:migrate をしておきます。
$ bin/rails db:create db:migrate
Controller と View を作る
Book controller と index View を作ります。
$ bin/rails g controller books index
初期データを登録するメソッドを定義する
BooksController
に初期データを登録するプライベートメソッドinitialize_data
を作成します。
毎回同じデータでテストできるように、一旦、データを削除してから、Author
,Book
,Edition
のデータを作成するようにします。app/controllers/books_controller.rbclass BooksController < ApplicationController ... private def initialize_data Author.first&.destroy author = Author.create(name: 'Dave Tomas') book = Book.create(title: 'Pragmatic Programer', author: author) Edition.create([{ name: '1st', book: book }, { name: '2nd', book: book }]) end endmodel に値を修正するメソッドを追加する
各モデルにそれぞれの値を更新するメソッドを追加します。
普通にDBの値を更新すると、今回の事象が確認できないので、Threadを作って、Thread の中で更新します。
Thread#join
を使って更新が終わるまで待つようにします。Book モデルの title を更新するメソッドを追加します。
app/models/book.rbclass Book < ApplicationRecord ... def self.fix_title Thread.start do Book.where(title: 'Pragmatic Programer').update(title: 'Pragmatic Programmer') end.join end end同じように、Author モデルの name を更新するメソッドを追加します。
app/models/author.rbclass Author < ApplicationRecord ... def self.fix_name Thread.start do Author.where(name: 'Dave Tomas').update(name: 'Dave Thomas') end.join end endEdition モデルにも name を更新するメソッドを追加します。
app/models/edition.rbclass Edition < ApplicationRecord ... def self.fix_name Thread.start do Edition.where(name: '2nd').update(name: '20th Anniversary Edition') end.join end end
book.reload
のキャッシュの動作を試すメソッドを作る
book.reload
のキャッシュの動作を試すプライベートメソッドを作ります。
book.reload
の前にbook
のtitle
を更新します。app/controllers/books_controller.rbclass BooksController < ApplicationController ... private ... # try book.reload def try_book_reload book = Book.first @old_title = book.title Book.fix_title @new_title = book.reload.title end end
book.reload_author
のキャッシュの動作を試すメソッドを作る
book.reload_author
のキャッシュの動作を試すプライベートメソッドを作ります。
book.reload_author
の前にauthor
のname
を更新します。
更新の前後で、Author.find
を呼び出します。app/controllers/books_controller.rbclass BooksController < ApplicationController ... private ... # try book.reload_author def try_book_reload_author book = Book.first author_id = Author.first.id @old_author_name = Author.find(author_id).name Author.fix_name @reloaded_author_name = book.reload_author.name @new_author_name = Author.find(author_id).name end end
book.editions.reload
を試す
book.editions.reload
のキャッシュの動作を試すプライベートメソッドを作ります。
book.editions.reload
の前にedition
のname
を更新します。app/controllers/books_controller.rbclass BooksController < ApplicationController ... private ... # try book.editions.reload def try_book_editions_reload book = Book.first @old_editions = book.editions.reload.map(&:name) Edition.fix_name @new_editions = book.editions.reload.map(&:name) end endindex メソッドを修正する
index メソッドを修正します。
これまで作ったプライベートメソッドを順に呼び出します。
index は GET メソッドなので、データを登録したり更新したりするのは RESTful ではないので、良くないです。
今回は動作確認のためなので、見逃してください。app/controllers/books_controller.rbclass BooksController < ApplicationController def index initialize_data try_book_reload try_book_reload_author try_book_editions_reload end ... endView を作成する
Controller で求めた値を表示するように View を修正します。
app/views/books/index.html.erb<h1>Books#index</h1> <table> <thead> <tr> <th>variable</th> <th>value</th> </tr> </thead> <tbody> <tr> <td>@old_title</td> <td><%= @old_title %></td> </tr> <tr> <td>@new_title</td> <td><%= @new_title %></td> </tr> <tr> <td>@old_author_name</td> <td><%= @old_author_name %></td> </tr> <tr> <td>@reloaded_author_name</td> <td><%= @reloaded_author_name %></td> </tr> <tr> <td>@new_author_name</td> <td><%= @new_author_name %></td> </tr> <tr> <td>@old_editions</td> <td><%= @old_editions %></td> </tr> <tr> <td>@new_editions</td> <td><%= @new_editions %></td> </tr> </tbody> </table>Rails 5 では
画面を表示すると以下のようになります。
データを更新していますが、@new_author_name
の値と@new_editions
の値は変わっていません。
キャッシュが働いているためです。
Rails 6 では
画面を表示すると以下のようになります。
@new_author_name
の値と@new_editions
の値は更新後の値に変わっています。試したソース
試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try043_query_cache参考情報
- 投稿日:2019-07-01T12:10:07+09:00
なぜサードパーティ・ライブラリを避けるべきなのか?
最近のプログラミング言語1は標準ライブラリが充実していますが、標準ライブラリが使いにくいために、別のサードパーティが普及している事も多いです。
例えばRubyでは、標準ライブラリの
net/http
に対し、faraday
がよく使われます。しかし、私は先日あるプロジェクトであえて
faraday
を避けnet/http
を使うことを選びました。私は以下のような理由から、サードパーティ・ライブラリは避けるべき(時もある)と思っています。昔話:Pythonをシェルスクリプトで書き直した
「シェルスクリプトをPythonで」ではありません。
若い頃あるプログラムを任された私は「RHELなら標準でPythonがインストールされている。このプログラムは RHEL でしか動かさないんだから、Pythonで書いてもいいだろう。PythonはBashより可読性も高いし、クールだ!」と考え、Pythonで書いた結果、先輩にゲンコツ(の絵文字)を食らいました。
というのも、任されたプログラムが、商用パッケージのアップデート用スクリプトだったからです。「RHELでしか動かさない」ものの、RHEL のバージョンは顧客によりまちまちでした(4.x 〜 5.x)。
Python では複数のバージョンで動くスクリプトを書くのは注意が必要です(2.4にはwith文が無い!)。気を付けて書いたとしても、そのスクリプトが将来のバージョンでも動く保証はありません(2.5では
with
という変数名は使えない!)。一方、シェルスクリプトはどのRHELでも同じように動作することが期待できます(少なくともPythonよりは確実性が高い)。
サードパーティはコントロールできない
さて、サードパーティ・ライブラリの話です。
サードパーティ・ライブラリはあなたの所有物ではありません。ゆえに、ライブラリが削除されたり、大きな変更が加わったりすることを止めることはできません。
これが如実に現れたのが、2016年のleft-pad問題でした2。left-padというライブラリが公開停止されたことで、それに推移的に依存していたReactやBabelなどの有名ライブラリが動作しなくなったのです。
「left-padは極端な例だろう」と思われるでしょう。でも、メジャーバージョンアップで後方互換性が無くなるのは、珍しいことではありません。そうなったら、
- 自分のコードを新バージョン向けに修正する(もちろん、テスト等の工数もかかる)
- もはやメンテされない旧バージョンを使い続ける(場合によってはフォーク版を作る)
という選択に迫られます。
そんなリスクを追うぐらいなら、多少不便でも標準ライブラリで書いた方が良いのではないですか?
そのサードパーティ、そんなに重要?
さて結局、サードパーティ・ライブラリを使うかどうかは、
- バージョンアップ時の書き換えにかかるコスト
- 得られる利便性
この2つを天秤にかけることになります。
あなたが書いているのが「長期間使うが滅多に変更はしないコード」の場合は、「最後に触ったのが3年前だから勘所が思い出せない」「開発環境構築から始めないといけない」「保守フェーズなので工数が取れない」といったことが起きがちなので、最初に標準ライブラリと多少格闘した方が、後々のコストは安いでしょう。一方、書き捨てスクリプトや、頻繁に手を加えるコード0なら、書き換えのコストはゼロあるいは低くなります。
また、例えばPythonでデータ分析処理を書くとき
pandas
やnumpy
といったライブラリは不可欠でしょう(明らかに利便性がコストに勝ります)。一方、付加的な処理(分析結果の保存とか)で楽をするためにrequests
を導入するというなら、それはちょっと考え直した方がいいかもしれません。
"Batteries included" が売りのPythonは1991年登場なので「最近」という表現はちょっと変ですが。 ↩
left-pad については、こちらの記事で解説されています: NPMとleft-pad : 私たちはプログラミングのやり方を忘れてしまったのか? | POSTD ↩
- 投稿日:2019-07-01T10:26:25+09:00
Ruby mysql2 で prepareする際の注意点
Ruby mysql2の動作でよくわからないところ
Ruby mysql2でqueryとprepareで動作が違う。これが仕様なのかどうなのかわからない。
バージョン
ruby : ruby 2.1.1.p76
mysql2 : 0.5.2準備
検証用テーブルを作成。
create.sqlCREATE TABLE t_test ( no int(11) DEFAULT NULL, test_date date DEFAULT NULL, article varchar(256) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;検証用データを挿入。
insert into t_test values ('1',now(),'date on'), ('2',null,'date null'), ('3','0000-00-00','date space') ;データ確認
mysql> select * from t_test ; +------+------------+------------+ | no | test_date | article | +------+------------+------------+ | 1 | 2019-07-01 | date on | | 2 | NULL | date null | | 3 | 0000-00-00 | date space | +------+------------+------------+ 3 rows in set (0.00 sec) mysql> select * from t_test where test_date is null; +------+-----------+-----------+ | no | test_date | article | +------+-----------+-----------+ | 2 | NULL | date null | +------+-----------+-----------+ 1 row in set (0.00 sec) mysql> select * from t_test where test_date <> '0000-00-00'; +------+------------+------------+ | no | test_date | article | +------+------------+------------+ | 3 | 0000-00-00 | date space | +------+------------+------------+ 1 row in set (0.00 sec)ま、当たり前の結果。
Rubyからデータを取得してみる。
queryで抽出してみる。
mysql2_query.rb#! /usr/local/bin/ruby require 'mysql2' require 'pp' cli = Mysql2::Client.new(:host => '127.0.0.1', :username => '***', :password => '***', :database => '***' ,:encoding => 'utf8') sql1 = %{select no,test_date,article from t_test limit 10} ret1 = cli.query(sql1 ,:symbolize_keys => true) ret1.each do |row| p row endqueryでデータを呼び出すと普通に出力される。
[anno@sv1]~/bin% ./mysql2_query.rb {:no=>1, :test_date=>#<Date: 2019-07-01 ((2458666j,0s,0n),+0s,2299161j)>, :article=>"date on"} {:no=>2, :test_date=>nil, :article=>"date null"} {:no=>3, :test_date=>nil, :article=>"date space"} [anno@sv1]~/bin%prepare + executeで抽出してみる。
mysql2_prepare_1.rb#! /usr/local/bin/ruby require 'mysql2' require 'pp' cli = Mysql2::Client.new(:host => '127.0.0.1', :username => '***', :password => '***', :database => '***' ,:encoding => 'utf8') sql2 = %{select no,test_date,article from t_test limit ?} stmt = cli.prepare(sql2) ret2 = stmt.execute('10' ,:symbolize_keys => true) ret2.each do |row| p row end[anno@sv1]~/bin% ./mysql2_prepare_1.rb /usr/local/lib/ruby/gems/2.1.0/gems/mysql2-0.5.2/lib/mysql2/statement.rb:7:in `new': invalid date (ArgumentError) from /usr/local/lib/ruby/gems/2.1.0/gems/mysql2-0.5.2/lib/mysql2/statement.rb:7:in `each' from /usr/local/lib/ruby/gems/2.1.0/gems/mysql2-0.5.2/lib/mysql2/statement.rb:7:in `_execute' from /usr/local/lib/ruby/gems/2.1.0/gems/mysql2-0.5.2/lib/mysql2/statement.rb:7:in `block in execute' from /usr/local/lib/ruby/gems/2.1.0/gems/mysql2-0.5.2/lib/mysql2/statement.rb:6:in `handle_interrupt' from /usr/local/lib/ruby/gems/2.1.0/gems/mysql2-0.5.2/lib/mysql2/statement.rb:6:in `execute' from ./mysql2_prepare_1.rb:18:in `<main>' [anno@sv1]~/bin%prepareでデータを呼び出すとエラーが出る。invalid date???
prepare + executeで抽出してみる(その2)。
dateでエラーとのことなので、日付がnullのデータを排除してselectしてみると成功。
mysql2_prepare_2.rb#! /usr/local/bin/ruby require 'mysql2' require 'pp' cli = Mysql2::Client.new(:host => '127.0.0.1', :username => '***', :password => '***', :database => '***' ,:encoding => 'utf8') sql2 = %{select no,test_date,article from t_test where test_date <> '0000-00-00' limit ?} stmt = cli.prepare(sql2) ret2 = stmt.execute('10' ,:symbolize_keys => true) ret2.each do |row| p row end[anno@sv1]~/bin% ./mysql2_prepare_2.rb {:no=>1, :test_date=>#<Date: 2019-07-01 ((2458666j,0s,0n),+0s,2299161j)>, :article=>"date on"} [anno@sv1]~/bin%結論
理由はわからないけど、prepareでデータ抽出をするときは日付データがnullは許容されないらしい。
- SQL側で文字列に変化させてからデータ抽出をする
- prepareをあきらめてqueryで抽出する
- テーブル構造で日付にnull,0000-00-00を許容しない様子にする。 どれかで対処する。
- 投稿日:2019-07-01T10:17:53+09:00
配列のメソッドまとめ!
こんにちは!
最近雨模様が続いてますね...
梅雨が明けて真夏の日々が待ち遠しいです
(←夏生まれ)
はい!
今回は、ブロックを扱う配列のメソッドの中でも、特に使用頻度の高いメソッドをまとめていきます!
それではLet's GO!
mapメソッド
mapメソッドは各要素に対してブロックを評価した結果を新しい配列に返します!
具体例を交えながら説明していきますね!
例えば、以下のように配列の各要素に5を足した新しい配列を作るコードがあります。
sample.rbnumbers = [0,1,2,3,4,5] plus_numbers = [] numbers.each do |number| plus_numbers << number + 5 end plus_numbers #=> [5,6,7,8,9,10]ここでmapメソッドの登場です!!!
mapメソッドを使うと、ブロックの返り値が配列の要素となる新しい配列が形成されるため、mapメソッドの返り値をそのまま変数に入れることができます!
それでは見てみましょう!
sample.rbnumbers = [0,1,2,3,4,5] plus_numbers = numbers.map do |number| number + 5 end plus_numbers #=> [5,6,7,8,9,10]selectメソッド
selectメソッドは、各要素に対してブロックを評価して、その返り値が真の要素を集めた配列を返すメソッドです!
同じく具体例を交えながら説明していきますね!
例えば、以下のようにすると、"e"を含んだ値だけを集めた配列を新たに作ることができます!
sample.rbcolors = ["red","blue","yellow","black"] new_colors = colors.select do |color| color.include?('e') end new_colors #=> ["red","blue","yellow"]rejectメソッド
rejectメソッドはselectメソッドの反対で、ブロックの返り値が真になった要素を除外した配列を返します!
例えば、以下のようにすると、"e"を含んだ値を除いた配列を新たに作ることができます!
sample.rbcolors = ["red","blue","yellow","black"] new_colors = colors.reject do |color| color.include?('e') end new_colors #=> ["black"]findメソッド
findメソッドは、ブロックの返り値が真になった最初の要素を返します!
例えば、以下のようにすると、"e"を含んだ最初の要素を返します!
sample.rbcolors = ["red","blue","yellow","black"] new_colors = colors.find do |color| color.include?('e') end new_colors #=> ["red"]
以上となります!
配列のメソッドは使い方次第でとても便利なので知っておくだけでもかなり幅が広がると思いました!
何かご意見等ございましたら、お気軽にコメントお願いします!
ご静聴ありがとうございました!
- 投稿日:2019-07-01T03:08:31+09:00
任意の文字列の最初の2文字を最後尾に持ってきて その文字を出力するメソッド
任意の文字列の最初の2文字を最後尾に持ってきて その文字を出力するメソッドの作り方
ex)
left2('Hello') → 'lloHe'
left2('Ruby') → 'byRu'
left2('oh') → 'oh'def left2(str) left2 = str.slice!(0,2) puts str + left2 endslice!メソッドを調べても出てこなかったので、ご存知の方は教えていただけると幸いです。
<参考記事>
・https://ref.xaio.jp/ruby/classes/string/slice
・https://ref.xaio.jp/ruby/classes/array/slice
・https://www.javadrive.jp/javascript/array_class/index8.html
- 投稿日:2019-07-01T00:24:58+09:00
tan(x)を何度も微分する
はじめに
だいぶ前ですが、Twitterで「RT(Favだったかな?)の数だけtan(x)を微分する」というつぶやきを見ました。わりとRT/Favされてて収拾がつかなくなっていたようです。
$\tan(x)$は$\sin(x) / \cos(x)$なので、一度微分すると、
$$
\frac{d}{dx} \tan{x} = \frac{1}{\cos^2{x}}
$$もう一度微分すると、
$$
\frac{d^2}{dx^2} \tan{x} = \frac{2 \sin{x}}{\cos^3{x}}
$$と、いい感じにややこしくなっていきます。
最近、シンボリックな微分コードが欲しくなったところだったので、その練習として、tan(x)を微分するコードを書いてみましょう。
方針
$\tan{x}$を微分するとき、$\tan{x} = \sin{x}/\cos{x}$にして、$f(x)/g(x)$という分数の微分公式、
$$
\frac{d}{dx} \frac{f(x)}{g(x)} = \frac{f'(x) g(x) - f(x)g'(x)}{g^2(x)}
$$を使いたくなります。しかし、プログラムで微分する場合は、
$$
\tan{x} = \cos^{-1}{x} \sin{x}
$$という形にしたほうが扱いやすいです。
いま、$\cos{x}$と$\sin{x}$のべき乗の積、$\cos^m{x} \sin^n{x}$を考えましょう。これを微分すると、
$$
\frac{d}{dx} \cos^{m}{x} \sin^{n}{x}
= -m \cos^{m-1}{(x)} \sin^{n+1}{(x)}
+ n \cos^{m+1}{(x)} \sin^{n-1}{(x)}
$$と、やはり$\cos^m{x} \sin^n{x}$の形しかでてきません。なので、$\tan{x} = \cos^{-1}{x} \sin{x}$という形からスタートして、後は上記のルールに従って計算していけば、何度でも微分できることになります。
コード
というわけで、そのままコードに落としてみましょう。デフォルト値があるハッシュを使えばあっという間です。$\cos^{m}{x}\sin^{n}{x}$を、
[m,n]
という配列で表し、この配列をキーとして、係数v
をハッシュとして登録しましょう。def diff(h) h2 = Hash.new(0) h.each do |key, v| m, n = key h2[[m-1,n+1]] += v*n if !m.zero? h2[[m+1,n-1]] -= v*m if !n.zero? end h2 end h = Hash.new h[[-1,1]] = 1 5.times do h = diff(h) p h end実行するとこんな感じです。
$ ruby tan.rb
{[-2, 2]=>1, [0, 0]=>1} {[-3, 3]=>2, [-1, 1]=>2} {[-4, 4]=>6, [-2, 2]=>8, [0, 0]=>2} {[-5, 5]=>24, [-3, 3]=>40, [-1, 1]=>16} {[-6, 6]=>120, [-4, 4]=>240, [-2, 2]=>136, [0, 0]=>16}これを見て気が付きました。
$\cos^{m}{x}\sin^{n}{x}$を、
[m,n]
という配列で表すと、これを微分すると[m+1, n-1]
と[m-1, n+1]
しか出てきません。つまり、$\cos^m{x}$と$\sin^n{x}$の係数の和m+n
は常に一定です。最初に$\tan{x} = \cos^{-1}{x} \sin{x}$からスタートしているので、常に$m+n=0$が成立します。つまり、$\tan{x}$を何度微分しても、$\tan{x}$のべき乗の線形和で表せる、ということです。
改めて微分の式を書くとこんな感じになります。
\begin{align} \frac{d}{dx} \tan{x} &= \tan^2{x} + 1 \\ \frac{d^2}{dx^2} \tan{x} &= 2 \tan^3{x} + \tan{x} \\ \frac{d^3}{dx^3} \tan{x} &= 6 \tan^4{x} + 8\tan^2{x} + 2\\ \end{align}これを、パスカルの三角形的な形にするとこんな感じになるでしょう。
で、ここまで考えたところで、Twitterで先行研究があることを教えていただきました。
これhttps://t.co/iAc8z5HeLW
— Keigo Nitadori (@k_nitadori) 2019年6月22日
ですかね?あるだろうなと思ってましたが、やっぱりありましたね・・・
まとめ
Rubyで$\tan{x}$を何度も微分するコードを書いてみました。っていうか、コードを書く前に「$\tan{x}$を何度微分しても$\tan{x}$のべき乗しか出てこない」という事実に気が付かなかったのはアホすぎますね。
この、
tan(x)
を何度も微分して、その係数がどんどん増えてややこしくなっていくという奴、なんとなくL Systemを思い出しますね。参考文献
- 投稿日:2019-07-01T00:04:50+09:00
【Ruby】1 - 0.8� = 0.2 にしたい (浮動小数点誤差)
小数点の演算で誤差がでてしまった
> 1 - 0.8 => 0.19999999999999996
0.2
を期待しているのに、誤差が生じてしまってます。
引かれるほうに小数点つけても同じ。> 1.0 - 0.8 => 0.19999999999999996bigdecimalをrequireすると良い、とあったのでやってみました。
> require 'bigdecimal' > BigDecimal("1") - BigDecimal("0.8") => 0.2e0BigDecimalの引数はString型にして、誤差のない数を演算機に伝えてる(と理解した)。
答えに指数部分がついてきました。理由はわからなかったけど、to_fすれば指数部分は消えました。(あとで調べる)> require 'bigdecimal' > (BigDecimal("1") - BigDecimal("0.8")).to_f => 0.2答えに整数が欲しいとき
例えば消費税計算とか。1800 * 1.08 の答えは1944が返ってきて欲しいのに、、、
> 1800 * 1.08 => 1944.0000000000002こういう時にBigDecimal使う。
> require 'bigdecimal' => true > (BigDecimal("1800") * BigDecimal("1.08")).ceil => 1944ceilは「自身と等しいかより大きな整数のうち最小のものを返す」のでBigDecimal使わないとこうなる。
> (1800 * 1.08).ceil => 1945参考
- 投稿日:2019-07-01T00:04:50+09:00
1 - 0.8� = 0.2 にしたい(浮動小数点問題)
浮動小数点問題でちょっと苦しんだのでメモします。Rubyです。
小数点の演算で誤差がでてしまった
> 1 - 0.8 => 0.19999999999999996
0.2
を期待しているのに、誤差が生じてしまってます。
引かれるほうに小数点つけても同じ。> 1.0 - 0.8 => 0.19999999999999996ググったらbigdecimalをrequireすると良い、とあったのでやってみました。なおBigDecimalの引数はString型にしないとエラーになるもよう。
> require 'bigdecimal' >(BigDecimal("1") - BigDecimal("0.8")).to_f => 0.2ちなみにto_fしないと指数がついてくる。なぜなのか。
> require 'bigdecimal' >(BigDecimal("1") - BigDecimal("0.8")).to_f => 0.2e0以下「プロを目指す人のためのRuby入門」の人の記事から(答えに整数が欲しいとき)
参考にしたのはこのQiitaです。
[Ruby]消費税計算にはBigDecimalを使いましょう例えば消費税計算とか。1800 * 1.08 の答えは1944が返ってきて欲しいのに、、、
> 1800 * 1.08 => 1944.0000000000002こういう時にBigDecimal使う。
> require 'bigdecimal' => true > (BigDecimal("1800") * BigDecimal("1.08")).ceil => 1944ceilは「自身と等しいかより大きな整数のうち最小のものを返す」のでBigDecimal使わないとこうなる。
> (1800 * 1.08).ceil => 1945ふむふむ。
ポエムです
抽象化と具体化が苦手なので(プログラミングするにあたって致命的なのでは...)、手元にメモ帳と電卓を置いて勉強しているんですが、パソコンの演算結果に誤差が出て慌てました。今の自分の頭で理解できる範囲だと、これがいいのかなと思ったのですが、他に最適解ありそう。(to_fしたりroundで丸めたり、とかも考えたのですがいい感じの桁数を判断するのって難しいなと思ったり...)
- 投稿日:2019-07-01T00:04:50+09:00
【Ruby】1 - 0.8� = 0.2 にしたい(浮動小数点問題)
浮動小数点問題でちょっと苦しんだのでメモします。Rubyです。
小数点の演算で誤差がでてしまった
> 1 - 0.8 => 0.19999999999999996
0.2
を期待しているのに、誤差が生じてしまってます。
引かれるほうに小数点つけても同じ。> 1.0 - 0.8 => 0.19999999999999996ググったらbigdecimalをrequireすると良い、とあったのでやってみました。なおBigDecimalの引数はString型にしないとエラーになるもよう。
> require 'bigdecimal' >(BigDecimal("1") - BigDecimal("0.8")).to_f => 0.2ちなみにto_fしないと指数がついてくる。なぜなのか。
> require 'bigdecimal' >(BigDecimal("1") - BigDecimal("0.8")).to_f => 0.2e0以下「プロを目指す人のためのRuby入門」の人の記事から(答えに整数が欲しいとき)
参考にしたのはこのQiitaです。
[Ruby]消費税計算にはBigDecimalを使いましょう例えば消費税計算とか。1800 * 1.08 の答えは1944が返ってきて欲しいのに、、、
> 1800 * 1.08 => 1944.0000000000002こういう時にBigDecimal使う。
> require 'bigdecimal' => true > (BigDecimal("1800") * BigDecimal("1.08")).ceil => 1944ceilは「自身と等しいかより大きな整数のうち最小のものを返す」のでBigDecimal使わないとこうなる。
> (1800 * 1.08).ceil => 1945ふむふむ。
ポエムです
抽象化と具体化が苦手なので(プログラミングするにあたって致命的なのでは...)、手元にメモ帳と電卓を置いて勉強しているんですが、パソコンの演算結果に誤差が出て慌てました。今の自分の頭で理解できる範囲だと、これがいいのかなと思ったのですが、他に最適解ありそう。(to_fしたりroundで丸めたり、とかも考えたのですがいい感じの桁数を判断するのって難しいなと思ったり...)