- 投稿日:2019-03-07T23:49:27+09:00
Railsで新しいプロジェクトを始めた時に必ずやっておきたい2つの設定
こんにちは、とくめいチャットサービス「ネコチャ」運営者のアカネヤ(@ToshioAkaneya)です。
今回はRailsで新しいプロジェクトを始めた時にやっておきたい2つの設定を紹介します。
重要ですので、必ずやっておきましょう。Railsで新しいプロジェクトを始めた時にやっておきたい2つの設定
turbolinksを無効化する
詳しくはこちらの記事で解説していますのでご覧下さい。
Railsでページ遷移後にJavaScriptが実行されない問題の解消法
これを行わないと、JavaScriptが思うように動作しないことがあります。rails consoleが動くようにする
$ rails consoleはとても重要なコマンドですが、最近のバージョンではエラーが発生してしまうことがあります。Gemfilegroup :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'rb-readline' endGemfileに
gem 'rb-readline'を追加して、$ bundleを実行して下さい。以上です。
はてなブックマーク・Pocketはこちらから
- 投稿日:2019-03-07T23:22:52+09:00
プログラミング学習記録19〜突っ走る力〜
今日やったこと
- Udemyの「Web開発入門完全攻略コース - プログラミングをはじめて学び創れる人へ!未経験から現場で使える開発スキルを習得!」のセクション12の139~150
- セクション13の151~194
以下、パートごとに書いたメモです。
セクション12AWS Cloud9による開発環境構築
139.イントロダクション-AWS Cloud9による開発環境構築-
AWS Cloud9を使うとwebアプリケーションの開発がwebブラウザでできるようになります。
1年間無料で利用できます。※ローカルPC上に環境構築して運用する方法もあります。
AWS Cloud9利用に必要なものは、
- メールアドレス
- クレジットカード
- ユーザー認証用の電話番号
です。
実行環境はGoogle chromeで行います。
140.AWSの無料利用枠について
具体的に結論としては、
新規アカウント作成から12ヶ月。月間750時間まで無料利用枠で利用可能。1年間の無料期間が終わってからは、(ドル円相場にもよるが)1ヶ月に90時間あたりだいたい210円くらいかかるみたいです。安いですね。
詳細は以下のページで確認してください。
AWS クラウド無料利用枠 | AWS(https://aws.amazon.com/jp/free/)よくある質問 - AWS クラウド無料利用枠 | AWS(https://aws.amazon.com/jp/free/faqs/)
141.AWS利用時の注意事項!!必ず確認してください!!
アカウント情報の管理は厳重にしましょう。
以下のような被害も実際に出てきています↓
『AWSで不正アクセスを受けたので、そのときの対応を記録しておく(返金されました)』
https://qiita.com/kojiro_ueda/items/503d24b313a3a80b8eccあと、知識がない状態でAWSのいろいろなサービスを利用するのは、セキュリティ面や費用の面で危険だということです。
知識をつけてから、わかるものから少しづつ手をつけていきましょう。
142.AWSアカウント作成
AWSアカウント作成についてです。
以下のページに具体的な流れが書かれています。
AWS アカウント作成の流れ | AWS(https://aws.amazon.com/jp/register-flow/)143.IAMの設定
AWS Identity and Access Management (IAM) は、ユーザーに対して AWS へのアクセスを安全に制御するための仕組みです。
AWS Identity and Access Management (IAM - ユーザのアクセスを安全に制御)| AWS(https://aws.amazon.com/jp/iam/) より引用
この講座ではIAMユーザーとしての利用で進めていくようです。
144.無料利用枠の使用のアラートの受信設定
AWSの不正な請求を防ぐためにあらかじめ行っておくべき設定です。
145.Cloud9のセットアップ
IAMユーザーでCloud9のセットアップを行いました。
これでIDE(統合開発環境)の準備ができました。
146.Cloud9の画面説明
linuxコマンド
$ ruby -v
でインストールされているrubyのバージョンを確認しました。147.補足:AWS Cloud9のテキストエディタの設定について
AWS Cloud9の設定に関する補足資料です。
AWS Cloud9のテキストエディタの設定について
(https://programmingnavi.com/1690/)Tabキーでスペース2個作れるようにするのと、不可視文字を表示する設定です。
148.新・Rubyのバージョン管理1
複数の開発案件を抱えていると、複数のrubyのバージョンを扱うことがあります。
なので、複数のrubyのバージョンを管理する方法を学びましょう、という話です。
Rubyのバージョン管理ソフトウェアはいくつかありますが、この講座ではrvmを使って進んでいきます。
Cloud9にインストールされているrvmのバージョンを確認しました。
$ rvm helpでrvmのヘルプを出すことができ、コマンドを調べることができます。
149.Rubyのバージョン管理2
鍵のインストールについてです。
150.Rubyのバージョン管理3
Rubyの最新バージョンは2.6.0ですが、動画に合わせてrvmで2.5.0をインストールし、デフォルトに指定しました。
このパートで実際に入力したコマンドです↓
$ rvm list
でインストールされているrubyのバージョンが確認できます。
$ rvm install 2.◯.◯
で指定したバージョンのrubyがインストールできます。
$ rvm use rubyのバージョン
でインストールされているrubyの中から使いたいバージョンを選ぶことができます。
$ rvm remove rubyのバージョン
で指定したバージョンのrubyをアンインストールできます。
$ ram —default use rubyのバージョン
でインストールされているrubyの中から指定したいものをデフォルトに指定することができます。セクション12AWS Cloud9による開発環境構築 全体の感想
Cloud9についてより詳しくなれました。
Cloud9を使うのは初めてではないのですが、複数のバージョンを管理する方法等は知らなかったので、知れてよかったです。
とりあえず開発環境構築まで来れて一安心という感じですね。
いよいよ次のセクションではRubyに入ります。
楽しみです。
ということで、気を引き締めて次のセクションに進みたいと思います。
セクション13Ruby入門
151.イントロダクション-Ruby入門-
このセクションの概要。
152.Rubyとは
Rubyはプログラミング言語でruby on railsはフレームワーク。
詳しい情報は公式HPで確認できます。
Rubyとは
(https://www.ruby-lang.org/ja/about/)153.動作確認環境について
この講座ではAWS Cloud9でRubyのバージョンは2.5.0で行います。
154.はじめてのRubyプログラミング
Rubyを動かす方法はirb(対話型評価環境)を使う方法とファイルに保存したプログラムを実行する方法の2つがあります。
このパートでは両方の方法を試してみました。
Irbはコマンド
$ irb
で起動します。元の画面に戻るときは
exit
です。ファイルに保存したプログラムを実行する方法ではProgateのコマンドラインでやったコマンドを使いました。
kinu:~/environment/ruby_projects $ pwd
/home/ec2-user/environment/ruby_projects
kinu:~/environment/ruby_projects $ ruby hello.rb
Hello World!Rubyのファイルは実行したいファイルの親ディレクトリに移動してから$ ruby 〇〇.rb で実行します。
155.コメント
Atomと同じようにCloud9でもcommandキー+/キーでコメントアウトします。
156.ローカル変数
price1=100や_price=100のような変数は原則使わないようにしましょう。
price_costのように_で区切るのは使われますが、priceCostのような書き方はあまり使いません。
あと、Rubyの予約語として指定されているものは変数名に使えません。
Ruby 予約語
157.定数
定数は全て大文字で書くことが多いです。
例
TAX=1.08
TAX_RATE=1.08定数への代入は一度きり。
158.リテラル
Rubyのプログラムの中に直接記述できる値のことをリテラルと言います。
数字や文字列、配列、ハッシュはリテラルです。
159.オブジェクト指向プログラミング言語イントロ
オブジェクトとは、データや処理の集まりのことです。
今は言葉をざっくり知っていればいいそうです。
クラス、インスタンス、メソッドについてのざっと学びました。
160.数値(Numeric)
基本的な計算方法と数値を扱うメソッドのついての動画です。
161.文字列(String)
文字列を途中で改行したい場合は、\nを間に入れてダブルクオーテーションで囲む必要があります。
特殊文字や式展開を行うときは、ダブルクオーテーション。それ以外はシングルクオーテーション、という使い分がオススメらしいです。
162.空白文字について
出力結果は変わらないが、10 + 1 - 3 のように空白を入れると見やすくなるので、空白を入れて書きましょう。
163.演算子による値の比較
2つの値の大小や同じかどうかを調べる方法についてです。
関係が成り立つ場合は真(true)、成り立たない場合は偽(false)が返ってきます。例えば、
puts 1<2
と書いたら、trueが返ってきます。164.演算子の優先順位
どの順番で計算されるのか?という話です。
詳しくはこちらでご確認ください。
演算子の優先順位(https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html)165.数値と文字列は暗黙的に変換されない
原則、数値と文字列をつなげることはできないので、.to_iや.to_f、.to_sを使って変換する必要があります。
166.インクリメントとデクリメント
インクリメントとは、値に1を足すことです。
デクリメントとは、値から1を引くことです。
Rubyには、JavaScriptでいうところの++、—はありません。
なので、インクリメントはn=n+1、n+=1のように、デクリメントはn=n-1、n-=1のように表現します。
167.真偽値
Rubyの真偽値のルール
・falseまたはnilであれば偽(false)
・それ以外は全て真(true)その他真偽値に関係するメソッドにも軽く触れました。
168.条件分岐if
点数によって異なる評価を示すプログラムと動物の種類によって、ターミナルに出力する鳴き方を変えるプログラムを作りました。
169.条件分岐 unless
unlessは条件式がfalseの時に実行したい処理を書きます。
unlessにelsifに相当するものはないので、無理に使う必要はありません。
n=1 unless n.zero? puts ‘0ではありません’ endを実行すると「0ではありません」が出力される。
170.条件分岐 case
複数の条件を指定する場合は、elsifを何個も使うよりもcaseを使った方がわかりやすくなります。
誕生石から、誕生月を出力するプログラムをcaseを使って作りました。
stone = 'ruby' case stone when 'ruby' puts '7月' when 'peridot' puts '8月' when 'sapphire' puts '9月' else puts 'データが登録されていません' end171.演習:条件分岐
年齢によってテーマパークの入場料を出し分けてターミナルに出力するプログラムを作る演習です。
これは簡単でした。
172.演習回答:条件分岐
模範回答と同じでした。
age = 5 if age >= 12 puts "5000円" elsif age >=6 puts "2500円" else puts "1000円" end173.メソッド
メソッドは複数の処理をまとめて、扱いやすくしたものです。
Progateでは戻り値にreturnを使っていたのですが、この講座ではreturnを使っていません。
returnを使わなくても、大丈夫みたいです。
174.演習:FizzBuzz
有名な問題ですね。
会社の採用面接で問われることもあるそうです。なんとかクリアできてよかったです。
175.演習回答:FizzBuzz
ポイントは先に15で割り切れる数の処理を書くことですね。
def fizz_buzz(n) if n%15==0 'FizzBuzz' elsif n%3==0 'Fizz' elsif n%5==0 'Buzz' else n.to_s end end puts fizz_buzz(1) puts fizz_buzz(2) puts fizz_buzz(3) puts fizz_buzz(4) puts fizz_buzz(5) puts fizz_buzz(6) puts fizz_buzz(7) puts fizz_buzz(8) puts fizz_buzz(9) puts fizz_buzz(10) puts fizz_buzz(11) puts fizz_buzz(12) puts fizz_buzz(13) puts fizz_buzz(14) puts fizz_buzz(15)3でも5でも割り切れない数字は文字列に変えて出力してください、ということで、n.to_sにしてます。
参考
- to_i→文字列を数字に変えるメソッド
- to_s→数字を文字列に変えるメソッド
176.puts,print,p
putsは改行されてnulになりますが、printは改行されずにnulが出ます。
Pメソッドはデバック用のメソッドです。
177.配列
配列の基本と配列に関する様々なメソッドについて学習しました。
具体的に、どの場面でどのメソッドを使うかはわからないので、さらっと流して次に進みます。
(0..25).to_a
で0から25の数字を含んだ配列を作ることができます。178.ハッシュ
連想配列とも呼ばれるものです。
each文の書き方がProgateでやったものとは違っていましたが、基本的な考え方に大きな違いは’ないので、このまま突き進みます。
179.繰り返し処理
繰り返し処理の概要。
180.繰り返し処理 each, for
原則、for文は書かないそうです。
配列とハッシュそれぞれでeach文を書いてみました↓
numbers = [1,2,3,4,5] numbers.each do |number| puts number end scores = {nakamura:90,sato:80,suzuki:70} scores.each do |name,score| puts "#{name},#{score}" end181.繰り返し処理 times
配列を使わずに指定した回数繰り返したい時に使います。
5.times do puts 'hello' end 5.times do |i| puts "#{i}.hello" endこの時、iは1からではなく、0から始まります。
182.繰り返し処理while
指定した条件が真である限り繰り返す処理です。
条件を指定せずに無限ループにならないように注意しましょう。
183.繰り返し処理 upto,downto
Uptoは数値を1ずつ増やしながら何かしらの処理をしたい時に使い、downtoは1ずつ減らしながら何かしらの処理をしたい時に使います。
184.繰り返し処理 step
指定した数字から指定した数字まで指定した数字ずつ増えていく処理をしたい時に使います。
構文は、開始式.step(上限値、一度に上限する大きさ)
185.繰り返し処理 loop, break, next
Loopはあえて無限ループを作りたい時に使います。
Breakで指定したところで中断させることができます。
Nextを使うと、同じブロック内のnext以降の処理が行われずに次の繰り返しが行われます。
186.クラス
クラスは設計図のようなもので、インスタンスは実体と考えることもできます。
用意されているクラスもたくさんあるのですが、自分でクラスを作る方法を学びました。
Progateではinitializedメソッドの中のインスタンス変数はself.name=nameのように記述していたのですが、この講座では@name=nameのように記述していました。
違いはありますが、基本的な考え方は一緒ですね。
class User def initialize(name) puts 'initialize!!' @name = name end def hello puts "Hello! I am #{@name}." end end emma = User.new('Emma') emma.hello olivia = User.new('Olivia') olivia.hello187.アクセサ
attr_accessorなどのアクセサについてです。
インスタンス変数の値を読み書きするメソッドのことをアクセサメソッドと言います。
アクセサメソッドには読み取り専用のもの、書き込み専用のものもあります。
具体的な使用場面についてはまだよくわかっていませんが、切った貼ったができる便利なものだというニュアンスはわかった気がします。
188.訂正:クラスメソッド、クラス変数
189のスペルミスのお詫びです。
189.クラスメソッド、クラス変数
クラスメソッドは、インスタンスを生成せずにクラスから直接呼ぶことができるメソッドです。
クラス変数は、クラス自体に値を保持することができる変数です。
190.クラスの継承
継承とは、親クラスを受け継いで使うことです。
継承を使うことで、共通部分を繰り返し書く必要がなくなるので、楽にコーディングできますね。
子クラスの方でオーバーライド(上書き)すると子クラスの方が優先されます。
191.メソッドのアクセス権
メソッドのアクセスできる条件を指定することができます。
メソッドのアクセス権には3つの種類があります。
Public→クラスの外部からでも自由に呼び出せる(デフォルト)
Private→クラスの内部でのみ使えます
Protected→これはあまり使われないそうです。
メソッドの上にprivateと書くだけでprivate化できます。
192.モジュール
モジュールはクラスのようにメソッドや定数をまとめられるものです。
クラスのようにインスタンスを作ることはできませんが、関連するメソッドなどをまとめてグループ化したい時に手軽に使えるため、便利です。
193:例外
実務では例外が発生した時の処理を記述しておくことが大事だそうです。
194.Rubyのコーディングルール
プロジェクトメンバーと一緒にコーディングするときに参考にする共通のルールです。
The Ruby Style Guide (日本語)(https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md)
RuboCop(https://github.com/bbatsov/rubocop)
セクション13 Ruby入門 全体の感想
パソコンのバッテリー残量の関係でかなり急ぎ足で終わらせました。
まだまだ理解できたいないところだらけですが、Progateをやっていたこともあり、理解できる部分も多くありました。
ひとまず完走することを第一に考え、このまま突き進みます。
きっと2回、3回と繰り返し触れていけば簡単になるはず!!!
あと残り87パートになりました。このまま突っ走ります。
ということで、引き続き明日からもプログラミング学習頑張ります。
おわり
- 投稿日:2019-03-07T23:04:05+09:00
winmergeの使いかたメモ
備忘録です
Excelファイルに出力した差分を確認したい。その手順
①ダウンロード 64の方
②比較したいファイルをドラッグ&ドロップ
③エクセルなので、「展開プラグイン」の項目を
「CompareMSExcelFile.sct」に設定④「OK」をクリック
以下のURLに書いてあります。
参考:http://bashalog.c-brains.jp/18/04/03-180000.php
- 投稿日:2019-03-07T18:29:59+09:00
プログラミング学習 記録 Railsチュートリアル11,12章
11、12章終わりました
学習時間は4時間程。一周目なので完全に理解できていない。
11章
- アカウントの有効化
- Userモデルに有効化トークンや有効化ステータスを付与する
- ユーザー登録
- ユーザー認証
- アカウント有効化のメールを送信
覚えたこと
どうやらActivartionトークンが必要らしい
既存のユーザーモデルにアカウント有効化のコードを追加
class User < ApplicationRecord
attr_accessor :remember_token, :activation_token
before_save :downcase_email
before_create :create_activation_digest
validates :name, presence: true, length: { maximum: 50 }
メソッドも# メールアドレスをすべて小文字にする def downcase_email self.email = email.downcase end # 有効化トークンとダイジェストを作成および代入する def create_activation_digest self.activation_token = User.new_token self.activation_digest = User.digest(activation_token) endそしてテストの準備としてサンプルユーザーを最初から有効にしておく
seed.rbにactivated: true, acivated_at: Time.zone.nowを追記アカウント有効化のメール送信
送信する為にはAction MailerというライブラリをUserのメイラーに追加するらしい
Userメイラーの生成をしてrails generate mailer UserMailer account_activation password_reset
作られたtextbビューとhtmlビューに表示する内容を書いていく
ちなみに生成されたメイラーのレイアウトはapp/views/layoutsで確認できる
あとはuser_mailer.rbでアカウント有効化リンクを定義して、developmentで試して終了
authenticated?メソッド等重要な点もあるがあくまで記録なので省略
production環境でも出来るらしいが2周目に回します
- 投稿日:2019-03-07T15:40:32+09:00
Rails開発で最低限気をつけること(=気をつけてほしいこと)
概要
Rails開発で最低限気をつけること(=気をつけてほしいこと)をメモ
少し長いですがRailsを覚え始めの人に読んでいただければと。全般
タイポをしない
当たり前ですが、タイポの原因はタイピングをミスすることです
残念ながらrubyは動的型付け言語であり、タイポによるエラーはプログラム実行時に発生します
タイポを防ぐ方法として、
- Lintを活用する
- 変数はコピペする
- スペルが間違っていないか辞書 or Google で検索するようにする
などが挙げられます
上記を徹底し、 視覚的にタイポを防ぐ 、 タイピングをやめる ことでタイポ0を目指しましょうインデントを揃える
PullRequestを作成する前には、必ずコードのフォーマットを直しましょう
インデントが揃っていることはソフトウェアエンジニアのマナーの一つだと思いますString vs Symbol
Sybmolの方がパフォーマンスが良いため、できるだけStringではなくSymbolを使うようにしてください
理由は下記の記事を参考ください
Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい - Qiita
ifvsif notvsunlessrubyでは条件式の判定に、
ifif notunlessなどがあります
条件式が複雑かつ、否定演算子などが組み合わされると一気に可読性が低下し、バグの原因につながるため、
条件式では「常に正常系を」書くようにしています
いくつか例を挙げてみます例:
if ~ else構文if @record.save # 条件式は正常系 # 成功時の処理を書く else # 失敗時の処理を書く end例
unlessでGurad構文(=早期リターン)def process(record) return false unless record.valid? # 早期リターン(=条件式は正常系) # 以下、正常系の処理を実行 end「常に正常系を」を記述することのを推奨する理由については下記リンクを参考にしてみてください
ifとunlessの使い分けboolean型のメソッド名には末尾に
?をつける一般的に、rubyではbooleanを返すメソッドには末尾に
?をつける習慣があります
メソッド名の末尾に?がついていることで boolean を返すことがわかり可読性が上がりますぼっち演算子
&.をつけるrubyでは、2.3から
&.演算子(safe navigation operator = ぼっち演算子)が導入されました
実行時に nil なオブジェクトに対してメソッドチェーンを実行するとundifined method error for nil:NilClassと
なってしまうため、nilになる可能性のあるメソッドチェーン呼び出しには全て&.をつけるようにすべきですソースコードの責任の範囲を意識する
OOPの思想に沿って、ソースコードの責任の範囲を考えて設計&実装する
Rails開発はMVCに依存しがちになますが、もっと柔軟にクラスを切った方が良いと思います
また、アプリケーションやビジネスロジックに依存せず汎用的に使えるクラスはlib配下に記述することもおすすめします例として、下記のようにディレクトリを切ると良いかなと思います
- app - controllers - decorators - forms # form経由の値を扱う(Controllerをファットにさせない) - helpers - jobs - listeners # wisperなど、Observerパターンでcallbackを処理する - mailers - models - operators # ビジネスロジックを扱う(ControllerやModelをファットにさせない) - policies # punditなどで権限管理 - validators # 独自定義したバリデーション - values # Valueオブジェクト - lib - xxx - xxx - xxxController
before_actionでインスタンス変数への代入を控える
before_actionを複数記述した場合、記述した順番に実行されます
before_action内で、他のbefore_actionで代入された変数を呼び出すと、
プログラムが正しく動作するかどうかがbefore_actionを呼び出す順番に依存してしまい、
スパゲッティコードにつながってしまいます
可能であれば変数を取得できるメソッドを作成することをおすすめします×
before_actionを使うclass UsersController < ActionController::Base before_action :set_user, only: [:show] def show end def set_user @user = User.find(params[:id]) end end◯ 専用のメソッドを用意する
class UsersController < ActionController::Base def show end def user @user = User.find(params[:id]) end helper_method: user end
helper_method :userとすることで、viewファイルでも変数を参照できるようになりますインスタンス変数をメモ化する
ActiveRecord経由で取得するデータは、変数をメモ化することで値のキャッシュができます
展開された変数はリクエスト終了時にクリアされるため、可能な限りキャッシュすることをおすすめしますclass UsersController < ActionController::Base def show end def user # @note @user がnilの場合のみ代入され、nilでなければキャッシュされたデータを返す @user ||= User.find(params[:id]) end helper_method: user endレコードの保存処理を行う場合は
flashを表示するレコードの保存処理を行う場合は成功時&失敗時に合わせて適切なflashメッセージを表示するようにしてください
def create if @record.save redirect_to records_path flash[:success] = 'レコードの保存に成功しました' else render :new flash.now[:error] = 'レコードの保存に失敗しました' end end def destroy if @record.destroy redirect_to records_path, flash: { success: 'レコードを削除しました' } else redirect_to records_path, flash: { error: 'レコードを削除できませんでした' } end endまた、レコードの更新に失敗し
renderを実行する場合はflash.nowを使うようにしてください
参考: 【Rails】flashとflash.nowの違い - avosalmonのブログModel
belongs_toにはrequired: trueまたはpresence: trueをつける
belongs_toで必ず親となるレコードが存在する場合は、required: trueまたはpresence: trueを記述してください
has_one,has_manyにはclass_nameをつける
has_oneまたはhas_manyを使う場合は、class_nameオプションをつけることで、
モデルが取得できずエラーとなってしまうことを防ぐことができる場合があるため、記述するようにするべきです
必要に応じてforeign_keyも指定することをおすすめします
has_one,has_manyにはdependentオプションをつける削除時に
has_oneまたはhas_many先の子モデルに対する振る舞いをdependentオプションで定義できます
不要なレコードはDBのパフォーマンスにも影響が出るので、適切に設定することをおすすめします
dependentオプションについては、下記リンクで詳しく説明されていたので参照してみてくださいActiveRecord::has_manyのdependentオプション
バリデーションを記述する
DB層でのバリデーションが必要なカラムに対しては、
validatesメソッド等を使って
適宜バリデーションを記述する
また、必要に応じて適宜カスタムバリデーションを作成して再利用できるようにすることもおすすめします
カスタムバリデーションを実行するView
form_withを使うRails5.1からは
form_forとform_tagがform_withというインターフェースに統合され、
URLベース、スコープ、モデルを指定してformタグを生成できるようになりました※
form_forを使う場合はlocal: trueを設定してください
https://qiita.com/bluegirl_beer/items/a361171f653edcd888ad
form_forやform_withではモデルの指定でaction先を絞るrailsで自動生成されるpathって読みづらいですよね
form_forやform_withでは、渡すオブジェクトが保存されているかどうかで
createのアクションを実行するか、updateのアクションを実行するかを自動的に判別してくれます
また、必要に応じてmethodやactionオプションを渡すことで、アクション先を絞ることができますDB
migrationファイルでカラムを追加するときは
commentをつける
commentオプションをつけることで、生成されるスキーマファイルにコメントを追加できます
可能な限りコメントの追加をお願いしますclass CreateBlogs < ActiveRecord::Migration[5.1] def change create_table :blogs, comment: 'ブログ' do |t| t.string :title, comment: 'タイトル' t.text :body, comment: '本文' t.timestamps t.datetime :deleted_at end end end
- 投稿日:2019-03-07T14:30:42+09:00
heroku run rails db:migrateのエラー発生時の解決法
初投稿です。
Railsチュートリアル等でもよく見るエラーなので、メモとして残しておきます。環境
・cloud9
herokuを走らせようとしたらエラーが出た
cloud9上で
$ heroku run rails db:migrateと入力すると
$ heroku run rails db:migrate WARNING WARNING Node version must be >=8.0.0 to use this CLI WARNING Current node version: 6.15.0 WARNING /home/ec2-user/.nvm/versions/node/v6.15.0/lib/node_modules/heroku-cli/node_modules/@oclif/command/lib/command.js:28 async _run() { ^^^^「今バージョン6.15.0だけど8.0.0に上げてね」ということらしい。
1、node.jsアップデート
こちらを参照してversionを上げてく。
①今のversion確認
$ node --version v6.15.0②v8.0.0にアップデート
$ nvm install v8.0.0 v8.0.0 is already installed. Now using node v8.0.0 (npm v5.0.0)③今のversion確認
$ node --version v8.0.0アップデート成功。
④再度走らせてみる
$ heroku run rails db:migrate module.js:487 throw err; ^ Error: Cannot find module 'typescript' at Function.Module._resolveFilename (module.js:485:15) at Function.Module._load (module.js:437:25) at Module.require (module.js:513:17) at require (internal/module.js:11:18) at Object.<anonymous> (/home/ec2-user/.nvm/versions/node/v8.0.0/lib/node_modules/heroku-cli/node_modules/@oclif/config/lib/ts-node.js:5:22) at Module._compile (module.js:569:30) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:503:32) at tryModuleLoad (module.js:466:12) at Function.Module._load (module.js:458:3)違う問題が発生…
2、moduleを入れる
上から4行目に
Error: Cannot find module 'typescript'とあるので、こちらを参照。
⑤足りないmoduleを入れてみる。
$ npm install -g npm-install-missing /home/ec2-user/.nvm/versions/node/v8.0.0/bin/npm-install-missing -> /home/ec2-user/.nvm/versions/node/v8.0.0/lib/node_modules/npm-install-missing/bin/npm-install-missing added 2 packages, removed 2 packages and updated 12 packages in 10.625s ╭─────────────────────────────────────╮ │ │ │ Update available 5.0.0 → 6.9.0 │ │ Run npm i -g npm to update │ │ │ ╰─────────────────────────────────────╯ bash: ource: command not found$ npm-install-missing npm-install-missing: No modules seem to be missing. Huzzah!できた?
⑥再度実行
$ heroku run rails db:migrate module.js:487 throw err; ^ Error: Cannot find module 'typescript' at Function.Module._resolveFilename (module.js:485:15) at Function.Module._load (module.js:437:25) at Module.require (module.js:513:17) at require (internal/module.js:11:18) at Object.<anonymous> (/home/ec2-user/.nvm/versions/node/v8.0.0/lib/node_modules/heroku-cli/node_modules/@oclif/config/lib/ts-node.js:5:22) at Module._compile (module.js:569:30) at Object.Module._extensions..js (module.js:580:10) at Module.load (module.js:503:32) at tryModuleLoad (module.js:466:12) at Function.Module._load (module.js:458:3)うーん、変わらず…
3、npm install
その後heroku loginやheroku -v等をしても同じエラーが出て断念。
過去に僕が書いたこちら(teratail)を参考に色々実行してみる。⑦$ npm install
$ npm install npm notice created a lockfile as package-lock.json. You should commit this file. up to date in 0.098s⑧$ npm install -g heroku-cli
$ npm install -g heroku-cli npm WARN deprecated heroku-cli@7.0.9: 'heroku-cli' has been renamed 'heroku' npm WARN deprecated cross-spawn-async@2.2.5: cross-spawn no longer requires a build toolchain, use it instead /home/ec2-user/.nvm/versions/node/v8.0.0/bin/heroku -> /home/ec2-user/.nvm/versions/node/v8.0.0/lib/node_modules/heroku-cli/bin/run added 1 package and updated 14 packages in 26.604s⑨$ heroku run rails db:migrate
$ heroku run rails db:migrate › Warning: heroku-cli update available from 7.0.9 to 7.22.2. Running rails db:migrate on ⬢ hukumiru... up, run.9955 (Free) D, [2019-03-07T04:59:18.403914 #4] DEBUG -- : (65.5ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY) D, [2019-03-07T04:59:18.417964 #4] DEBUG -- : (10.8ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL) D, [2019-03-07T04:59:18.420152 #4] DEBUG -- : (0.9ms) SELECT pg_try_advisory_lock(4540128404952329490) D, [2019-03-07T04:59:18.449576 #4] DEBUG -- : (1.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC D, [2019-03-07T04:59:18.457883 #4] DEBUG -- : ActiveRecord::InternalMetadata Load (1.1ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]] D, [2019-03-07T04:59:18.466155 #4] DEBUG -- : (0.8ms) BEGIN D, [2019-03-07T04:59:18.468570 #4] DEBUG -- : SQL (1.1ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "production"], ["created_at", "2019-03-07 04:59:18.466682"], ["updated_at", "2019-03-07 04:59:18.466682"]] D, [2019-03-07T04:59:18.470396 #4] DEBUG -- : (1.5ms) COMMIT D, [2019-03-07T04:59:18.471489 #4] DEBUG -- : (0.9ms) SELECT pg_advisory_unlock(4540128404952329490)通った…
まとめ
とりあえず、これで走るようになりました。
正直どれが原因でどれが解決に繋がったのかまだよく分かってないですが、個人的によく見るエラーでしたので残しておいて、詳しく分かり次第、また追記します。
詳しい方、教えていただけると助かります。
- 投稿日:2019-03-07T13:50:40+09:00
Factory_girlからFactory_botに変更したときに詰まった話
ちょっと古いシステムの改修担当になり
環境整えたときにもろもろチェックしていたらFactory_girlを使っていたので
これをFactory_botに変更するときにすこし躓いたので備忘録程度のメモ。何はともあれ、Gemの修正
Factory_girl_railsがGemfileにかかれていたので
これをFactory_bot_railsに変更してbundle install- gem "factory_girl_rails" + gem "factory_bot_rails"※うちのプロジェクトではユニコーン周りでいろいろ干渉したため
bundle install --without productionを実行正直これだけで大丈夫だと思ってた。
無事にgemのインストールが完了したのでテストしてみると
なにやらfactories以下のファイルでエラーが発生。コードも何も修正してないのになんで?って思っていろいろググる
そしたら伊藤さんの記事に出会う。
factory_bot 4.11で非推奨になった静的属性(static attributes)まさかと思って自分の
Gemfile.lockを確認しにいくと・・・factory_bot (5.0.2) activesupport (>= 4.2.0) factory_bot_rails (5.0.1) factory_bot (~> 5.0.0) railties (>= 4.2.0)Oh...
4.11どころか更に上の5.0.2まで上がってるのね。。
(2019/2/9にアプデされた様子)ということでコードを静的属性から動的属性に修正
記事内容にも書かれているように、
4.11からファクトリ定義が
静的属性のままでは警告が出る仕様に変更になっている
(そしてバージョン5で完全に削除されている)ので、
これを自分のコードにも反映。FactoryGirl.define do factory :test do trait :default do hogehoge "TEST_TEMP" fugafuga "テスト用デフォルトテンプレート" delete_flg 0 end end endから
FactoryBot.define do factory :test do trait :default do hogehoge { "TEST_TEMP" } fugafuga { "テスト用デフォルトテンプレート" } delete_flg { 0 } end end end定義に
{}をつけるだけの簡単なお仕事。
※1行目のGirlからBotへの修正も忘れずに・・!これで、テストが通るようになったのでめでたし。
今回は、修正箇所がそこまで多くなかったので
手作業で変更していったがrubocop-rspecのgemをインストールして
以下のコマンドを実行すれば一括で修正してくれるみたい(便利rubocop \ --require rubocop-rspec \ --only FactoryBot/AttributeDefinedStatically \ --auto-correct
- 投稿日:2019-03-07T13:07:25+09:00
Openbd APIを使って本レビューアプリを作成する。 ( jQuery,Ajax 使用 )
初めまして。qiita初投稿になります。
業務未経験なため、間違いがある箇所もあると思いますがご指摘頂ければと思います。
今回書くことは基礎的なことですが、私のようなrails初心者のお力になれれば幸いです。作成するレビューアプリの概要
- openbdというAPIを使用し、ajaxを利用して非同期で本の情報を取得します。
- あらかじめ用意したフォームに取得した任意の情報が自動入力され、レビューを入力し、投稿ボタンを押す事でreviewが投稿されます。
- DBには画像はURLのみ保存し、画像自体は保存しません。
- 取得する情報がない場合(画像や紹介文)は、「情報がありません」旨を表示させます。
- bootstrap4を使用しviewを作成します。
アプリ構築環境
- ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
- Rails 5.2.2
アプリの作成の流れ
1.アプリを作成し、必要なgem(bootstrap4等)を導入します。
2.reviewsコントローラを作成します。
3.本情報およびレビューを格納するためのReviewモデルを作成します。
4.フォームを表示するためのviewを作成します。
5.非同期(ajax)で本情報を取得するためのjsファイルを作成します。
6.投稿したレビューを表示させるためのviewを作成します。
7.railsサーバを起動します。1.アプリ作成
以下のコマンドでアプリを作成します。
rails new book_reviewアプリが作成出来たらGemfileを編集します。
cd book_review vi Gemfile以下のGemをファイルの一番下に記述します。
Gemfilegem 'haml-rails' #erbではなくhamlで記述するために導入します。 gem 'erb2haml' #既存のerbファイルをhamlに変換します。 gem 'jquery-rails' #railsでjqueryを利用するために導入します。 gem 'bootstrap' #versionをしていないのでbootstrap4がインストールされます。 gem 'bootstrap_form' #formを自動でbootstrapレイアウトにしてくれます。いつものようにbundleインストールします。
bundle installbootstrap4とbootstrap_formを使用するために以下のファイルに記述します。
book_review/app/assets/stylesheets/配下のファイルを
application.cssからapplication.scssに名前変更してください。application.scss@import "bootstrap";application.scss*= require rails_bootstrap_formsjavascriptも使用するため、以下のファイルにも以下を記述します。
//= require_tree .の上に記述してくださいapp/assets/javascripts/application.js//= require rails-ujs //= require activestorage //= require turbolinks //= require jquery3 //追加 //= require bootstrap-sprockets //追加 //= require bootstrap //追加 //= require_tree .以上で、bootstrap4とjavascriptが利用可能になります。
いよいよ、アプリ作成に入っていきます。
まずはデフォルト状態ではapplicationはerbで書かれているのでhamlに変更します。以下のコマンドを入力してください。rake haml:replace_erbs2.reviewsコントローラ作成
以下のコマンドでreviewsコントローラを作成します。
rails g controller reviews show new # showとnewを記述することで、show.html.haml,new.html.hamlも同時に作成してくれます。上記コマンドでエラーが出た場合はGemfileを編集し、sqlite3のバージョンを指定してください
Gemfilegem 'sqlite3', '~> 1.3.6'作成できたらreviews_controllerを編集します。
app/controllers/reviews_controller.rbclass ReviewsController < ApplicationController def show @review = Review.find(params[:id]) end def new @review = Review.new respond_to do |format| format.html format.json ##jsonで出力します。 end end def create @review = Review.new(review_params) if @review.save redirect_to root_path else redirect_to new_review_path end end def review_params #ストロングパラメータで制限する。 params.require(:review).permit(:name, :author, :review, :image_url, :introduction) end end合わせてレビューを投稿するためのルーティングも編集します。
config/routes.rbroot 'reviews#new' # 今回はindexページがないので、review投稿ページをrootにします。 resources :reviews #resourcesとすることで自動的にルーティングを作成してくれます。 #作成されたrouteは rails routesコマンドで確認可能です。3.Reviewモデル作成
レビューを格納するためにreviewモデルを作成します。
rails g model Review name:string author:string review:text image_url:string introduction:text上記コマンドで以下のテーブルとカラムが作成されます。
reviewsテーブル
Column Type Options name string author string review text introduction text image_url string 作成したmigrationファイルをdbにmigrateします。
rails db:migrate4.本情報取得フォーム作成
以下のviewファイルを作成し、編集します。
bootstrap_formというgemを使用しているため、form_forをbootstrap_form_forとしています。
自動でbootstrapのスタイルが適用されます。app/views/reviews/new.html.haml.container .result .panel-title 本情報取得フォーム .form-group{id:"get-book"} %input{type:"text",class:"form-control",placeholder:"ISBNを入力して下さい",id:"isbn"} .form-submit %button{type:"submit",id:"submit",class:"btn btn-outline-dark"} 本検索 .result-image = bootstrap_form_for @review ,id:"form-result" do |f| = f.text_field :name,label: "タイトル",placeholder:"本のタイトルを入力して下さい",id:"book-name" = f.text_field :author,label: "著者",placeholder:"著者の名前を入力して下さい",id:"author-name" = f.text_area :introduction,type:"hidden",hide_label: true,id:"introduction",style:"display:none" = f.text_field :image_url,type:"hidden",hide_label: true, id:"image_url" = f.text_area :review,label: "レビュー",placeholder:"レビューを入力して下さい",size: "20x10",id:"review" = f.submit "投稿",class:"btn btn-outline-dark"5.本情報取得jsファイル作成
book_review/app/assets/javascripts/の配下にreviews.js.erbを作成します。
拡張子にerbを入れているのは画像がなかった際のno_image画像をrailsのimagesフォルダから参照するためです。app/assets/javascripts/reviews.js.erb$(document).on('turbolinks:load', function() { //画像のHTMLを生成する。 function buildImage(book) { var no_image = '<div class="book_image"><img "width="200" height="200" src="<%= image_path('no_image.jpg')%>"></div>'; var image = '<div class="book_image img-thumbnail"><img "width="250" height="250" + src="' + book[0].summary.cover + '"></div>'; if (!book[0].summary.cover){ var image = no_image; //画像がなかった場合の処理 }else{ image; } return image; } //画像URLを生成する。 function imageUrl(book){ var no_image_url = '<%= image_path('/assets/no_image.jpg')%>'; var image_url = book[0].summary.cover; //".jpg"に"_0"を加える。最大サイズの画像を取得できるようになる。 var image_url = image_url.replace(".jpg", "_0.jpg"); if (!book[0].summary.cover){ var image_url = no_image_url; //画像がなかった場合の処理 }else{ image_url } return image_url; } function bookDetail (book){ var bookDetail = $.isEmptyObject(book[0].onix.CollateralDetail); if (bookDetail != true){ $('#introduction').val(book[0].onix.CollateralDetail.TextContent[0].Text); }else{ $('#introduction').val("情報がありません"); } } //著者の情報がなかった場合の処理 function authorName (book) { var bookAuthor = $.isEmptyObject(book[0].summary.author); if (bookAuthor != true){ $('#author-name').val(book[0].summary.author); }else{ $('#author-name').val("情報がありません"); } } //本の情報がなかった場合のalert function noAppendBook(){ var book = `<div class="alert alert-warning"> <strong>本情報を取得できませんでした。</strong> </div>` return book } //本の情報取得に成功した時のalert function appendBook(){ var book = `<div class="alert alert-primary"> <strong>本情報の取得に成功しました。</strong> </div>` return book } //情報取得後、再度検索バーに入力が開始されたらフォームに入力されている取得済み情報を削除する。 $('#get-book').on("keyup",function(){ $('#submit').prop('disabled', false); $('.alert').remove(); $('#book-name').val(""); $('#author-name').val(""); $('#image_url').val(""); $('#introduction').val(""); $('.book_image').empty(); }); //submitタグをクリックするとajaxで処理が開始される。 $('#submit').on("click",function(e) { e.preventDefault(); var bookName = $('#get-book').find('#isbn').prop('value'); var requestUrl = 'https://api.openbd.jp/v1/get?isbn='; requestUrl += bookName + '&pretty'; $.ajax({ type:"GET", url:requestUrl, dataType:"json" }) //通信が成功したときの処理 .done(function(data) { if (data[0] != null){ var image = buildImage(data); // resultに成功失敗のalart表示 $('.result').append(appendBook); // 本のタイトル表示 $('#book-name').val(data[0].summary.title); //hiddenタグであるimage_urlに取得した画像urlを格納 $('#image_url').val(imageUrl(data)); // 取得した本の画像を表示 $('.result-image').append(image); // 本の著者表示 authorName(data); // 本の紹介文表示 bookDetail(data); // 本情報取得に成功後 submitタグを押せないようにする。 $('#submit').prop('disabled', true); } else { // 本情報取得に失敗した際のalert表示 $('.result').append(noAppendBook); // 本情報取得に成功後 submitタグを押せないようにする。 $('#submit').prop('disabled', true); } }) // 通信に失敗した際のalert表示 .fail(function() { alert('情報の取得に失敗しました'); }); }); });本の画像が取得できなかった場合に代わりの画像を表示するため、以下のパスに以下の名前で代替画像を配置してください。
パス: app/assets/images/
ファイル名: no_image.jpgちなみに私は以下のフリー素材サイトからとりました。
http://design-ec.com/?p=55これで、ブラウザで
localhost:3000/reviews/newにアクセスすると本情報入力フォームが現れ、
「本情報取得フォーム」にISBN番号を入力する事で本の情報を取得する事ができるようになりました。もし、フォームにISBNを入力しても反応がなかった場合、coffeeファイルが呼び出されてしまっている恐れがあるので、以下のファイルを削除してください。
app/assets/javascripts/reviews.coffee6.投稿したレビューを表示
上記の作業で、review投稿ページおよび本の情報を取得するためのjsファイルを作成しましたが、
まだレビューを表示するためのviewがないので作成します。app/views/reviews/show.html.haml%section.book-images-frame.col-md-3.col-xs-12 - if @review.image_url? = image_tag "#{@review.image_url}",class: "book-images-cover",style:"height:200px;width:150px;" - else = image_tag "no_image.jpg",class: "book-images-cover",style:"height:200px;width:150px;" %section.book-content.col-md-6.col-xs-12 .book-title-frame .book-title-block = @review.name .book-attribute-frame %h2 著者 .book-author = @review.author .book-content %h2 紹介 = simple_format (@review.introduction) %h2 レビュー = simple_format (@review.review)7.railsサーバを起動
rails s #サーバ起動完成
これで本のレビューを投稿後、自動的にレビューページに遷移してくれる簡単なアプリが作成できました。
が、
まだまだ未完成なので修正していって頂ければと思います。この記事は随時修正していこうと思いますが、
記事の間違いや、もっとこうしたほうがいいよ等ございましたら、コメント頂ければ幸いです。参考にさせて頂いた記事
- 投稿日:2019-03-07T13:07:25+09:00
Openbd APIを使って簡単な本レビューアプリを作成する。 ( jQuery,Ajax 使用 )
初めまして。qiita初投稿になります。
業務未経験なため、間違いがある箇所もあると思いますがご指摘頂ければと思います。
今回書くことは基礎的なことですが、私のようなrails初心者のお力になれれば幸いです。作成するレビューアプリの概要
- openbdというAPIを使用し、ajaxを利用して非同期で本の情報を取得します。
- あらかじめ用意したフォームに取得した任意の情報が自動入力され、レビューを入力し、投稿ボタンを押す事でreviewが投稿されます。
- DBには画像はURLのみ保存し、画像自体は保存しません。
- 取得する情報がない場合(画像や紹介文)は、「情報がありません」旨を表示させます。
- bootstrap4を使用しviewを作成します。
アプリ構築環境
- ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
- Rails 5.2.2
アプリの作成の流れ
1.アプリを作成し、必要なgem(bootstrap4等)を導入します。
2.reviewsコントローラを作成します。
3.本情報およびレビューを格納するためのReviewモデルを作成します。
4.フォームを表示するためのviewを作成します。
5.非同期(ajax)で本情報を取得するためのjsファイルを作成します。
6.投稿したレビューを表示させるためのviewを作成します。
7.railsサーバを起動します。1.アプリ作成
以下のコマンドでアプリを作成します。
rails new book_reviewアプリが作成出来たらGemfileを編集します。
cd book_review vi Gemfile以下のGemをファイルの一番下に記述します。
Gemfilegem 'haml-rails' #erbではなくhamlで記述するために導入します。 gem 'erb2haml' #既存のerbファイルをhamlに変換します。 gem 'jquery-rails' #railsでjqueryを利用するために導入します。 gem 'bootstrap' #versionをしていないのでbootstrap4がインストールされます。 gem 'bootstrap_form' #formを自動でbootstrapレイアウトにしてくれます。いつものようにbundleインストールします。
bundle installbootstrap4とbootstrap_formを使用するために以下のファイルに記述します。
book_review/app/assets/stylesheets/配下のファイルを
application.cssからapplication.scssに名前変更してください。application.scss@import "bootstrap";application.scss*= require rails_bootstrap_formsjavascriptも使用するため、以下のファイルにも以下を記述します。
//= require_tree .の上に記述してくださいapp/assets/javascripts/application.js//= require rails-ujs //= require activestorage //= require turbolinks //= require jquery3 //追加 //= require bootstrap-sprockets //追加 //= require bootstrap //追加 //= require_tree .以上で、bootstrap4とjavascriptが利用可能になります。
いよいよ、アプリ作成に入っていきます。
まずはデフォルト状態ではapplicationはerbで書かれているのでhamlに変更します。以下のコマンドを入力してください。rake haml:replace_erbs2.reviewsコントローラ作成
以下のコマンドでreviewsコントローラを作成します。
rails g controller reviews show new # showとnewを記述することで、show.html.haml,new.html.hamlも同時に作成してくれます。上記コマンドでエラーが出た場合はGemfileを編集し、sqlite3のバージョンを指定してください
Gemfilegem 'sqlite3', '~> 1.3.6'作成できたらreviews_controllerを編集します。
app/controllers/reviews_controller.rbclass ReviewsController < ApplicationController def show @review = Review.find(params[:id]) end def new @review = Review.new respond_to do |format| format.html format.json ##jsonで出力します。 end end def create @review = Review.new(review_params) if @review.save redirect_to review_path(@review) else redirect_to new_review_path end end def review_params #ストロングパラメータで制限する。 params.require(:review).permit(:name, :author, :review, :image_url, :introduction) end end合わせてレビューを投稿するためのルーティングも編集します。
config/routes.rbroot 'reviews#new' # 今回はindexページがないので、review投稿ページをrootにします。 resources :reviews #resourcesとすることで自動的にルーティングを作成してくれます。 #作成されたrouteは rails routesコマンドで確認可能です。3.Reviewモデル作成
レビューを格納するためにreviewモデルを作成します。
rails g model Review name:string author:string review:text image_url:string introduction:text上記コマンドで以下のテーブルとカラムが作成されます。
reviewsテーブル
Column Type Options name string author string review text introduction text image_url string 作成したmigrationファイルをdbにmigrateします。
rails db:migrate4.本情報取得フォーム作成
以下のviewファイルを作成し、編集します。
bootstrap_formというgemを使用しているため、form_forをbootstrap_form_forとしています。
自動でbootstrapのスタイルが適用されます。app/views/reviews/new.html.haml.container .result .panel-title 本情報取得フォーム .form-group{id:"get-book"} %input{type:"text",class:"form-control",placeholder:"ISBNを入力して下さい",id:"isbn"} .form-submit %button{type:"submit",id:"submit",class:"btn btn-outline-dark"} 本検索 .result-image = bootstrap_form_for @review ,id:"form-result" do |f| = f.text_field :name,label: "タイトル",placeholder:"本のタイトルを入力して下さい",id:"book-name" = f.text_field :author,label: "著者",placeholder:"著者の名前を入力して下さい",id:"author-name" = f.text_area :introduction,type:"hidden",hide_label: true,id:"introduction",style:"display:none" = f.text_field :image_url,type:"hidden",hide_label: true, id:"image_url" = f.text_area :review,label: "レビュー",placeholder:"レビューを入力して下さい",size: "20x10",id:"review" = f.submit "投稿",class:"btn btn-outline-dark"5.本情報取得jsファイル作成
book_review/app/assets/javascripts/の配下にreviews.js.erbを作成します。
拡張子にerbを入れているのは画像がなかった際のno_image画像をrailsのimagesフォルダから参照するためです。app/assets/javascripts/reviews.js.erb$(document).on('turbolinks:load', function() { //画像のHTMLを生成する。 function buildImage(book) { var no_image = '<div class="book_image"><img "width="200" height="200" src="<%= image_path('no_image.jpg')%>"></div>'; var image = '<div class="book_image img-thumbnail"><img "width="250" height="250" + src="' + book[0].summary.cover + '"></div>'; if (!book[0].summary.cover){ var image = no_image; //画像がなかった場合の処理 }else{ image; } return image; } //画像URLを生成する。 function imageUrl(book){ var no_image_url = '<%= image_path('/assets/no_image.jpg')%>'; var image_url = book[0].summary.cover; //".jpg"に"_0"を加える。最大サイズの画像を取得できるようになる。 var image_url = image_url.replace(".jpg", "_0.jpg"); if (!book[0].summary.cover){ var image_url = no_image_url; //画像がなかった場合の処理 }else{ image_url } return image_url; } function bookDetail (book){ var bookDetail = $.isEmptyObject(book[0].onix.CollateralDetail); if (bookDetail != true){ $('#introduction').val(book[0].onix.CollateralDetail.TextContent[0].Text); }else{ $('#introduction').val("情報がありません"); } } //著者の情報がなかった場合の処理 function authorName (book) { var bookAuthor = $.isEmptyObject(book[0].summary.author); if (bookAuthor != true){ $('#author-name').val(book[0].summary.author); }else{ $('#author-name').val("情報がありません"); } } //本の情報がなかった場合のalert function noAppendBook(){ var book = `<div class="alert alert-warning"> <strong>本情報を取得できませんでした。</strong> </div>` return book } //本の情報取得に成功した時のalert function appendBook(){ var book = `<div class="alert alert-primary"> <strong>本情報の取得に成功しました。</strong> </div>` return book } //情報取得後、再度検索バーに入力が開始されたらフォームに入力されている取得済み情報を削除する。 $('#get-book').on("keyup",function(){ $('#submit').prop('disabled', false); $('.alert').remove(); $('#book-name').val(""); $('#author-name').val(""); $('#image_url').val(""); $('#introduction').val(""); $('.book_image').empty(); }); //submitタグをクリックするとajaxで処理が開始される。 $('#submit').on("click",function(e) { e.preventDefault(); var bookName = $('#get-book').find('#isbn').prop('value'); var requestUrl = 'https://api.openbd.jp/v1/get?isbn='; requestUrl += bookName + '&pretty'; $.ajax({ type:"GET", url:requestUrl, dataType:"json" }) //通信が成功したときの処理 .done(function(data) { if (data[0] != null){ var image = buildImage(data); // resultに成功失敗のalart表示 $('.result').append(appendBook); // 本のタイトル表示 $('#book-name').val(data[0].summary.title); //hiddenタグであるimage_urlに取得した画像urlを格納 $('#image_url').val(imageUrl(data)); // 取得した本の画像を表示 $('.result-image').append(image); // 本の著者表示 authorName(data); // 本の紹介文表示 bookDetail(data); // 本情報取得に成功後 submitタグを押せないようにする。 $('#submit').prop('disabled', true); } else { // 本情報取得に失敗した際のalert表示 $('.result').append(noAppendBook); // 本情報取得に成功後 submitタグを押せないようにする。 $('#submit').prop('disabled', true); } }) // 通信に失敗した際のalert表示 .fail(function() { alert('情報の取得に失敗しました'); }); }); });本の画像が取得できなかった場合に代わりの画像を表示するため、以下のパスに以下の名前で代替画像を配置してください。
パス: app/assets/images/
ファイル名: no_image.jpgちなみに私は以下のフリー素材サイトからとりました。
http://design-ec.com/?p=55これで、ブラウザで
localhost:3000/reviews/newにアクセスすると本情報入力フォームが現れ、
「本情報取得フォーム」にISBN番号を入力する事で本の情報を取得する事ができるようになりました。もし、フォームにISBNを入力しても反応がなかった場合、coffeeファイルが呼び出されてしまっている恐れがあるので、以下のファイルを削除してください。
app/assets/javascripts/reviews.coffee6.投稿したレビューを表示
上記の作業で、review投稿ページおよび本の情報を取得するためのjsファイルを作成しましたが、
まだレビューを表示するためのviewがないので作成します。app/views/reviews/show.html.haml%section.book-images-frame.col-md-3.col-xs-12 - if @review.image_url? = image_tag "#{@review.image_url}",class: "book-images-cover",style:"height:200px;width:150px;" - else = image_tag "no_image.jpg",class: "book-images-cover",style:"height:200px;width:150px;" %section.book-content.col-md-6.col-xs-12 .book-title-frame .book-title-block = @review.name .book-attribute-frame %h2 著者 .book-author = @review.author .book-content %h2 紹介 = simple_format (@review.introduction) %h2 レビュー = simple_format (@review.review)7.railsサーバを起動
rails s #サーバ起動完成
これで本のレビューを投稿後、自動的にレビューページに遷移してくれる簡単なアプリが作成できました。
が、
まだまだ未完成なので修正していって頂ければと思います。この記事は随時修正していこうと思いますが、
記事の間違いや、もっとこうしたほうがいいよ等ございましたら、コメント頂ければ幸いです。参考にさせて頂いた記事
- 投稿日:2019-03-07T13:07:25+09:00
【Rails】openBD APIを使って簡単な本レビューアプリを作成する。【jQuery,Ajax 】
初めまして。qiita初投稿になります。
業務未経験なため、間違いがある箇所もあると思いますがご指摘頂ければと思います。
今回書くことは基礎的なことですが、私のようなrails初心者のお力になれれば幸いです。openBD APIについて
書誌情報・書影を、だれでも自由に使える、高速なAPIで提供しているプロジェクトです。
24,747社の約76万タイトルの本の書誌情報、書影、ためし読み、書評掲載情報を利用でき、
書誌情報1件あたり1ミリ秒以下での応答と非常に高速なAPIです。公式サイト
https://openbd.jp/作成するレビューアプリの概要
- openbdというAPIを使用し、ajaxを利用して非同期で本の情報を取得します。
- あらかじめ用意したフォームに取得した任意の情報が自動入力され、レビューを入力し、投稿ボタンを押す事でreviewが投稿されます。
- DBには画像はURLのみ保存し、画像自体は保存しません。
- 取得する情報がない場合(画像や紹介文)は、「情報がありません」旨を表示させます。
- bootstrap4を使用しviewを作成します。
アプリ構築環境
- ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
- Rails 5.2.2
アプリの作成の流れ
1.アプリを作成し、必要なgem(bootstrap4等)を導入します。
2.reviewsコントローラを作成します。
3.本情報およびレビューを格納するためのReviewモデルを作成します。
4.フォームを表示するためのviewを作成します。
5.非同期(ajax)で本情報を取得するためのjsファイルを作成します。
6.投稿したレビューを表示させるためのviewを作成します。
7.railsサーバを起動します。1.アプリ作成
以下のコマンドでアプリを作成します。
rails new book_reviewアプリが作成出来たらGemfileを編集します。
cd book_review vi Gemfile以下のGemをファイルの一番下に記述します。
Gemfilegem 'haml-rails' #erbではなくhamlで記述するために導入します。 gem 'erb2haml' #既存のerbファイルをhamlに変換します。 gem 'jquery-rails' #railsでjqueryを利用するために導入します。 gem 'bootstrap' #versionをしていないのでbootstrap4がインストールされます。 gem 'bootstrap_form' #formを自動でbootstrapレイアウトにしてくれます。いつものようにbundleインストールします。
bundle installbootstrap4とbootstrap_formを使用するために以下のファイルに記述します。
book_review/app/assets/stylesheets/配下のファイルを
application.cssからapplication.scssに名前変更してください。application.scss@import "bootstrap";application.scss*= require rails_bootstrap_formsjavascriptも使用するため、以下のファイルにも以下を記述します。
//= require_tree .の上に記述してくださいapp/assets/javascripts/application.js//= require rails-ujs //= require activestorage //= require turbolinks //= require jquery3 //追加 //= require bootstrap-sprockets //追加 //= require bootstrap //追加 //= require_tree .以上で、bootstrap4とjavascriptが利用可能になります。
いよいよ、アプリ作成に入っていきます。
まずはデフォルト状態ではapplicationはerbで書かれているのでhamlに変更します。以下のコマンドを入力してください。rake haml:replace_erbs2.reviewsコントローラ作成
以下のコマンドでreviewsコントローラを作成します。
rails g controller reviews show new # showとnewを記述することで、show.html.haml,new.html.hamlも同時に作成してくれます。上記コマンドでエラーが出た場合はGemfileを編集し、sqlite3のバージョンを指定してください
Gemfilegem 'sqlite3', '~> 1.3.6'作成できたらreviews_controllerを編集します。
app/controllers/reviews_controller.rbclass ReviewsController < ApplicationController def show @review = Review.find(params[:id]) end def new @review = Review.new respond_to do |format| format.html format.json ##jsonで出力します。 end end def create @review = Review.new(review_params) if @review.save redirect_to review_path(@review) else redirect_to new_review_path end end def review_params #ストロングパラメータで制限する。 params.require(:review).permit(:name, :author, :review, :image_url, :introduction) end end合わせてレビューを投稿するためのルーティングも編集します。
config/routes.rbroot 'reviews#new' # 今回はindexページがないので、review投稿ページをrootにします。 resources :reviews #resourcesとすることで自動的にルーティングを作成してくれます。 #作成されたrouteは rails routesコマンドで確認可能です。3.Reviewモデル作成
レビューを格納するためにreviewモデルを作成します。
rails g model Review name:string author:string review:text image_url:string introduction:text上記コマンドで以下のテーブルとカラムが作成されます。
reviewsテーブル
Column Type Options name string author string review text introduction text image_url string 作成したmigrationファイルをdbにmigrateします。
rails db:migrate4.本情報取得フォーム作成
以下のviewファイルを作成し、編集します。
bootstrap_formというgemを使用しているため、form_forをbootstrap_form_forとしています。
自動でbootstrapのスタイルが適用されます。app/views/reviews/new.html.haml.container .result .panel-title 本情報取得フォーム .form-group{id:"get-book"} %input{type:"text",class:"form-control",placeholder:"ISBNを入力して下さい",id:"isbn"} .form-submit %button{type:"submit",id:"submit",class:"btn btn-outline-dark"} 本検索 .result-image = bootstrap_form_for @review ,id:"form-result" do |f| = f.text_field :name,label: "タイトル",placeholder:"本のタイトルを入力して下さい",id:"book-name" = f.text_field :author,label: "著者",placeholder:"著者の名前を入力して下さい",id:"author-name" = f.text_area :introduction,type:"hidden",hide_label: true,id:"introduction",style:"display:none" = f.text_field :image_url,type:"hidden",hide_label: true, id:"image_url" = f.text_area :review,label: "レビュー",placeholder:"レビューを入力して下さい",size: "20x10",id:"review" = f.submit "投稿",class:"btn btn-outline-dark"5.本情報取得jsファイル作成
book_review/app/assets/javascripts/の配下にreviews.js.erbを作成します。
拡張子にerbを入れているのは画像がなかった際のno_image画像をrailsのimagesフォルダから参照するためです。app/assets/javascripts/reviews.js.erb$(document).on('turbolinks:load', function() { //画像のHTMLを生成する。 function buildImage(book) { var no_image = '<div class="book_image"><img "width="200" height="200" src="<%= image_path('no_image.jpg')%>"></div>'; var image = '<div class="book_image img-thumbnail"><img "width="250" height="250" + src="' + book[0].summary.cover + '"></div>'; if (!book[0].summary.cover){ var image = no_image; //画像がなかった場合の処理 }else{ image; } return image; } //画像URLを生成する。 function imageUrl(book){ var no_image_url = '<%= image_path('/assets/no_image.jpg')%>'; var image_url = book[0].summary.cover; //".jpg"に"_0"を加える。最大サイズの画像を取得できるようになる。 var image_url = image_url.replace(".jpg", "_0.jpg"); if (!book[0].summary.cover){ var image_url = no_image_url; //画像がなかった場合の処理 }else{ image_url } return image_url; } function bookDetail (book){ var bookDetail = $.isEmptyObject(book[0].onix.CollateralDetail); if (bookDetail != true){ $('#introduction').val(book[0].onix.CollateralDetail.TextContent[0].Text); }else{ $('#introduction').val("情報がありません"); } } //著者の情報がなかった場合の処理 function authorName (book) { var bookAuthor = $.isEmptyObject(book[0].summary.author); if (bookAuthor != true){ $('#author-name').val(book[0].summary.author); }else{ $('#author-name').val("情報がありません"); } } //本の情報がなかった場合のalert function noAppendBook(){ var book = `<div class="alert alert-warning"> <strong>本情報を取得できませんでした。</strong> </div>` return book } //本の情報取得に成功した時のalert function appendBook(){ var book = `<div class="alert alert-primary"> <strong>本情報の取得に成功しました。</strong> </div>` return book } //情報取得後、再度検索バーに入力が開始されたらフォームに入力されている取得済み情報を削除する。 $('#get-book').on("keyup",function(){ $('#submit').prop('disabled', false); $('.alert').remove(); $('#book-name').val(""); $('#author-name').val(""); $('#image_url').val(""); $('#introduction').val(""); $('.book_image').empty(); }); //submitタグをクリックするとajaxで処理が開始される。 $('#submit').on("click",function(e) { e.preventDefault(); var bookName = $('#get-book').find('#isbn').prop('value'); var requestUrl = 'https://api.openbd.jp/v1/get?isbn='; requestUrl += bookName + '&pretty'; $.ajax({ type:"GET", url:requestUrl, dataType:"json" }) //通信が成功したときの処理 .done(function(data) { if (data[0] != null){ var image = buildImage(data); // resultに成功失敗のalart表示 $('.result').append(appendBook); // 本のタイトル表示 $('#book-name').val(data[0].summary.title); //hiddenタグであるimage_urlに取得した画像urlを格納 $('#image_url').val(imageUrl(data)); // 取得した本の画像を表示 $('.result-image').append(image); // 本の著者表示 authorName(data); // 本の紹介文表示 bookDetail(data); // 本情報取得に成功後 submitタグを押せないようにする。 $('#submit').prop('disabled', true); } else { // 本情報取得に失敗した際のalert表示 $('.result').append(noAppendBook); // 本情報取得に成功後 submitタグを押せないようにする。 $('#submit').prop('disabled', true); } }) // 通信に失敗した際のalert表示 .fail(function() { alert('情報の取得に失敗しました'); }); }); });本の画像が取得できなかった場合に代わりの画像を表示するため、以下のパスに以下の名前で代替画像を配置してください。
パス: app/assets/images/
ファイル名: no_image.jpgちなみに私は以下のフリー素材サイトからとりました。
http://design-ec.com/?p=55これで、ブラウザで
localhost:3000/reviews/newにアクセスすると本情報入力フォームが現れ、
「本情報取得フォーム」にISBN番号を入力する事で本の情報を取得する事ができるようになりました。もし、フォームにISBNを入力しても反応がなかった場合、coffeeファイルが呼び出されてしまっている恐れがあるので、以下のファイルを削除してください。
app/assets/javascripts/reviews.coffee6.投稿したレビューを表示
上記の作業で、review投稿ページおよび本の情報を取得するためのjsファイルを作成しましたが、
まだレビューを表示するためのviewがないので作成します。app/views/reviews/show.html.haml%section.book-images-frame.col-md-3.col-xs-12 - if @review.image_url? = image_tag "#{@review.image_url}",class: "book-images-cover",style:"height:200px;width:150px;" - else = image_tag "no_image.jpg",class: "book-images-cover",style:"height:200px;width:150px;" %section.book-content.col-md-6.col-xs-12 .book-title-frame .book-title-block = @review.name .book-attribute-frame %h2 著者 .book-author = @review.author .book-content %h2 紹介 = simple_format (@review.introduction) %h2 レビュー = simple_format (@review.review)7.railsサーバを起動
rails s #サーバ起動完成
これで本のレビューを投稿後、自動的にレビューページに遷移してくれる簡単なアプリが作成できました。
が、
まだまだ未完成なので修正していって頂ければと思います。この記事は随時修正していこうと思いますが、
記事の間違いや、もっとこうしたほうがいいよ等ございましたら、コメント頂ければ幸いです。参考にさせて頂いた記事
- 投稿日:2019-03-07T13:01:12+09:00
[学習用]Rails5で画像投稿 CarrierWaveで最速保存
うっかり忘れたので構築した手順を忘れない様にメモ。
scaffold で一括作成
$ rails g scaffold shop title:string content:text name:string cat_id:integer user_id:integer image:stringまず、scaffold で一括作成。
ハマったポイント
このときimage:string も一緒に作ってしまう。
ここを忘れてて、画像が登録されないerrorに悩まされる。もし追加し忘れたら
$ rails g migration add_image_column_to_shops image:string $ rails db:migrateこれで大丈夫。
Gem CarrierWaveの追加
gem 'carrierwave'Gemfile に上記を追加して
$ bundleアップローダークラス生成
$ rails g uploader imageapp/uploader/image_uploader.rb が作成される
CarrierWave編集
app/uploaders/image_uploader.rbclass ImageUploader < CarrierWave::Uploader::Base storage :file # storage :fog def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end def extension_whitelist %w(jpg jpeg gif png) end # 画像名をリネームさせる(日付時間はダメ絶対) def filename "#{secure_token}.#{file.extension}" if original_filename.present? end protected def secure_token var = :"@#{mounted_as}_secure_token" model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid) end endはまったポイント
"#{Time.zone.now.strftime('%Y%m%d%H%M%S')}.jpg" if original_filename.present?
タイムゾーンにするとリサイズ時にエラーが出てサイズの変更ができなくなる。
エラー名が全然違うので、全くわからなかった。
RMagick入ってないよとかMiniMagick入ってないよとかそんなerrorが出てテンパる。追加
/app/models/shop.rbclass Shop < ApplicationRecord mount_uploader :image, ImageUploader endパラメータの確認
/app/controllers/posts_controller.rbprivate # Use callbacks to share common setup or constraints between actions. def set_shop @shop = Shop.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def shop_params params.require(:shop).permit(:title, :content, :cat_id, :name, :user_id, :image) endimage をscaffoldより後から追加したなら :imageを追加する。
image をscaffoldで追加したなら入っているか確認する。画像が表示できる様にする
画像を登録
/app/views/_form.html.erb<%= form.label :image %> <%= form.file_field :image %>変更、新規、編集の時に追加できるように。
表示側の追加
/app/views/show.html.erb<% if @shop.image? %> <%= image_tag @shop.image.url %> <% end %>
- 投稿日:2019-03-07T13:01:12+09:00
[学習用]Rails5:CarrierWaveで画像投稿+rmagickでサムネイル保存+画像名ランダム化
うっかり忘れたので構築した手順を忘れない様にメモ。
※ローカルテスト用。Herokuには保存できないので、AWSのS3に保存するときは
保存先を違うものに変更する必要がある。scaffold で一括作成
$ rails g scaffold shop title:string content:text name:string cat_id:integer user_id:integer image:stringまず、scaffold で一括作成。
ハマったポイント
このときimage:string も一緒に作ってしまう。
ここを忘れてて、画像が登録されないerrorに悩まされる。もし追加し忘れたら
$ rails g migration add_image_column_to_shops image:string $ rails db:migrateこれで大丈夫。
Gem CarrierWaveの追加
gem 'carrierwave'Gemfile に上記を追加して
$ bundleアップローダークラス生成
$ rails g uploader imageapp/uploader/image_uploader.rb が作成される
CarrierWave編集
app/uploaders/image_uploader.rbclass ImageUploader < CarrierWave::Uploader::Base storage :file # storage :fog def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end def extension_whitelist %w(jpg jpeg gif png) end # 画像名をリネームさせる(日付時間はダメ絶対) def filename "#{secure_token}.#{file.extension}" if original_filename.present? end protected def secure_token var = :"@#{mounted_as}_secure_token" model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid) end endはまったポイント
"#{Time.zone.now.strftime('%Y%m%d%H%M%S')}.jpg" if original_filename.present?
タイムゾーンにするとリサイズ時にエラーが出てサイズの変更ができなくなる。
エラー名が全然違うので、全くわからなかった。
RMagick入ってないよとかMiniMagick入ってないよとかそんなerrorが出てテンパる。追加
/app/models/shop.rbclass Shop < ApplicationRecord mount_uploader :image, ImageUploader endパラメータの確認
/app/controllers/posts_controller.rbprivate # Use callbacks to share common setup or constraints between actions. def set_shop @shop = Shop.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def shop_params params.require(:shop).permit(:title, :content, :cat_id, :name, :user_id, :image) endimage をscaffoldより後から追加したなら :imageを追加する。
image をscaffoldで追加したなら入っているか確認する。画像が表示できる様にする
画像を登録
/app/views/_form.html.erb<%= form.label :image %> <%= form.file_field :image %>変更、新規、編集の時に追加できるように。
表示側の追加
/app/views/show.html.erb<% if @shop.image? %> <%= image_tag @shop.image.url %> <% end %>画像のリサイズ
gem 'rmagick'$ bundleCarrierWave編集
app/uploaders/image_uploader.rbclass ImageUploader < CarrierWave::Uploader::Base # Include RMagick or MiniMagick support: include CarrierWave::RMagick # include CarrierWave::MiniMagick # Choose what kind of storage to use for this uploader: storage :file # storage :fog # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end # ファイルサイズに制限をつける def size_range 1..5.megabytes end # 画像の上限を640x480にする process :resize_to_limit => [640, 640] # サムネイル保存する version :thumb do process :resize_to_limit => [320, 320] end # 保存形式 process :convert => 'jpg' def extension_whitelist %w(jpg jpeg gif png) end # 拡張子が同じでないとGIFをJPGとかにコンバートできない def filename super.chomp(File.extname(super)) + '.jpg' if original_filename.present? end # ファイル名を日付にすると不具合が出る def filename "#{secure_token}.#{file.extension}" if original_filename.present? end protected def secure_token var = :"@#{mounted_as}_secure_token" model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid) end endViewにサムネイル追加
/app/views/show.html.erb<% if @shop.image? %> <%= image_tag @shop.image.url %> <% end %> <%= image_tag @shop.image.url(:thumb) %>これで640画像と320のサムネイル画像が表示される
これで忘れても大丈夫なはず。参考にしたサイト
https://nyoken.com/rails-carrierwave
- 投稿日:2019-03-07T12:38:32+09:00
Ruby | 配列の奇数番目と偶数番目を取り出す方法
配列の奇数番目や偶数番目を取り出して新たな配列にする
配列の中から偶数番目または奇数番目の要素を取り出したいときに役に立ったので共有します。
今回は、each_sliceメソッドとmapメソッドを使用してやってみました。参考記事
each_slice (Enumerable) - Rubyリファレンス
ある配列を任意の要素数の配列に分割したい - Qiita結論はこんな感じです。
ary = [1,2,3,4,5,6,7,8,9,10] odd = ary.each_slice(2).map(&:first) even = ary.each_slice(2).map(&:last) p odd #=>[1,3,5,7,9] p even #=>[2,4,6,8,10]少し分解して考えてみた
結論の書き方だと何をやっているのかイマイチ分かりにくいと思いますので、自分なりに分解してみました。
ある配列を任意の要素数の配列に分割したい - Qiita
each_sliceについては、上の記事が分かりやすく解説していました。
each_slice(数): 数の部分には何分割するかを決める数値を入れるなので、数の部分を
2とすると、配列を2つずつ取り出して、それをさらにmapメソッドで配列に入れている感じです。ary.each_slice(2).map {|n| n} #=>[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]これを利用して、以下のようにします。
odd = ary.each_slice(2).map {|n| n.first} #[1, 2].firstみたいなことを繰り返している #=>[1,3,5,7,9] even = ary.each_slice(2).map {|n| n.last} #=>[2,4,6,8,10]
- 取り出した配列
nの要素の1番目を取り出すと、奇数番目の配列が完成する。
つまりfirstメソッドを使用する。- 取り出した配列
nの要素の2番目を取り出すと、偶数番目の配列が完成する。
つまりlastメソッドを使用する。
初心者なりに考えたやり方になりますので、他にも色々なやり方がたくさんあると思います。
もしこんなやり方もあるよ!って方がいればぜひ教えていただければと思います。
読んでいただきありがとうございました。
- 投稿日:2019-03-07T09:04:07+09:00
無限ループ∞最短選手権
さぁみんな無限ループしよう。
最近、無限ループが流行りらしいので
各プログラミング言語(その辺にあった10個の言語)の
無限ループを比べてみます。
果たしてどの言語が1位に輝くのか!?※改行は1文字としてカウント。
(一応、全て実行してチェックしています)C (24文字)
int main(void){for(;;);}C⋕ (37文字)
class a{static void Main(){for(;;);}}C++ (20文字)
int main(){for(;;);}D (22文字)
void main(){for(;;){}}Go (31文字)
package main func main(){for{}}Java (54文字)
class a{public static void main(String[] a){for(;;);}}JavaScript (8文字)
for(;;);PHP (14文字)
<?php for(;;);Python (9文字)
while 1:0Ruby (11文字)
while 1 end【優勝】JavaScript
チャンピオンは"JavaScript"でした。さすが"JS"。
"JavaScript"は無限ループ界において最有力候補であると考えられますね。???「JSが優勝だと思っていたのか。」
【真の優勝】Ruby ※追記
Ruby(6文字)loop{}Ruby、6文字で無限ループが出来るとは……。
恐るびー最後に
もっと文字数減らせるよ!とか
もっと文字数が少ない言語あるぜ!最強だぜ!などなどありましたらコメントまたは編集リクエストでお願い致します。
- 投稿日:2019-03-07T09:04:07+09:00
?♀️無限ループ∞最短選手権?♂️
さぁみんな無限ループしよう。
最近、無限ループが流行りらしいので
各プログラミング言語(その辺にあった10個の言語)の
無限ループを比べてみます。
果たしてどの言語が1位に輝くのか!?※改行は1文字としてカウント。
(一応、全て実行してチェックしています)C (24文字)
int main(void){for(;;);}C⋕ (37文字)
class a{static void Main(){for(;;);}}C++ (20文字)
int main(){for(;;);}D (22文字)
void main(){for(;;){}}Go (31文字)
package main func main(){for{}}Java (53文字)
class a{public static void main(String[]a){for(;;);}}JavaScript (8文字)
for(;;);PHP (14文字)
<?php for(;;);Python (9文字)
while 1:0Ruby (11文字)
while 1 end【優勝】JavaScript
チャンピオンは"JavaScript"でした。さすが"JS"。
"JavaScript"は無限ループ界において最有力候補であると考えられますね。???「JSが優勝だと思っていたのか。」
【真の優勝】Ruby ※追記
Ruby(6文字)loop{}Ruby、6文字で無限ループが出来るとは……。
恐るびー???「6文字ごときが優勝だと思っていたのか。」
【本当の真の優勝】L00P ※追記(番外編)
L00P(0文字)0文字……圧巻です。
言語名からして、無限ループ界の頂点に君臨していると思われる風貌をしてますね……。このように上記で比べていた10個の言語以外の言語では、もっと文字数が少ないものがありました。
無限ループは奥が深い。最後に
もっと文字数減らせるよ!とか
もっと文字数が少ない言語あるぜ!最強だぜ!などなどありましたらコメントまたは編集リクエストでお願い致します。
- 投稿日:2019-03-07T07:43:40+09:00
引数の削除(Remove Parameter)
1つずつリファクタリング技法まとめ
個人的に簡単かつ取り入れ易いと思うものから目的
すぐ引き出せるようにする
基本作業サイクル
- システムを動かして仕様を精査
- テストメソッドを作成
- テストの失敗を確認
- テストの成功を確認
- 小さい変更、随時テスト実行(パターン追加失敗確認->成功確認)
- 最後テスト実行
- 最後動作確認
引数の削除(Remove Parameter)とは
メソッド本体が引数を使わなくなり、引数を削除するもの
引数の追加の逆ポイント
- 必要じゃなくなったものは消す。
- インスタンス変数として扱うべきでないか検討する
- 同じシグネチャのメソッドが存在しないか確認する(同じように削除する必要がある可能性がある)
例
def setting(url, id, password, date, logger) @date = date @logger = logger login = { url: url, id: id, password: password } end↓
def initialize(url, id, password, date, logger) @date = date @logger = logger end def setting(url, id, password) login = { url: url, id: id, password: password } end書籍情報
Jay Fields (著), Shane Harvie (著), Martin Fowler (著), Kent Beck (著),
長尾 高弘(訳), リファクタリング:Rubyエディション
https://amzn.to/2VlyWML雑感
「引数の追加」と「引数の削除」と「引数オブジェクトの導入」は一度にまとめて行えそう
- 投稿日:2019-03-07T03:10:22+09:00
Rubyのあれこれ
- 投稿日:2019-03-07T01:49:45+09:00
[備忘録]プログラミング学習_2(webエンジニアの将来、言語概念の学習)
投稿目的
個人的な学習記録
同じ初心者の技術力・モチベーションの向上本日の学習内容(webエンジニアの将来、言語概念の学習)
昨日(_1)、jsやReactの文法などの学習を行ったが、技術の需要や将来性、用途について一度考えようと思い今日は調べごとを中心に行った。
調べた事
1.Reactはjsのライブラリ。フレームワークじゃない。
ライブラリは各用途の便利グッズまとめ、フレームワークは起承転結楽々テンプレートって理解になった。
参考URL:(https://qita.com/azuki8/items/ad7710fdefaedc63e3f7)
2.KENTAさん動画にてキャリア考察
年齢・勉強・好奇心のリスクについて考えさせられた。業界の成熟的に50歳以上の正社員さんの数が現状少ないが、今の30代が20年後どのようなキャリアになっているのか気になる。何も考えずに楽しそうだけでWeb系エンジニアになるのは危険かもしれない。(Web系エンジニアという職業の3つのリスクである「年齢」「勉強」「好奇心」)
参考URL: (https://www.youtube.com/watch?v=YuOYjxpMI4w)
3.KENTAさん動画にて「わらしべ長者戦略」
私自身、新卒+テックエキスパートの手札で現在の内定先を獲得したので、業務を通して自分自身の手札を増やしつつステップアップする方法は正しいと感じた。一つの言語に固執して、廃れる可能性を日々考えるのは精神的にもよくないしね。
参考URL: (https://www.youtube.com/watch?v=eElCAwuDwsk)

