- 投稿日:2020-02-12T23:55:09+09:00
【備忘録】Ruby : クラス変数の使い方
sample.rbclass Num @@num = 1 #クラス変数 #インスタンスメソッドからでもクラスメソッドからでもアクセス可能 #異なるオブジェクトでも同じクラスであれば値は共有可能 #あまり使われることはないらしい def increment @@num += 1 end def decrement @@num -= 1 end def num puts @@num end def self.num puts @@num end end foo = Num.new foo.num #=> 1 foo.increment #+1 foo.num #=> 2 foo.decrement #-1 foo.num #=>1 foo.decrement #-1 fuga = Num.new fuga.num #=>0 #新しいオブジェクトを作ったのにも関わらず、fooオブジェクトでの処理を引き継いでいる。 #引き継がない場合は 1 からスタートするはず。
- 投稿日:2020-02-12T23:47:06+09:00
【Rails】flashメッセージをフェードアウトで消す方法【JavaScript】
はじめに
この記事では、flashメッセージを表示したあと一定時間後にフェードアウトさせる方法を解説します。
flashメッセージ系の記事はたくさんあるのですが、
どれもbootstrap
を使用してたり
何やら複雑な方法だったり(Hamlハムル??とかrenderとかややこしい!)。。もっと簡単な記事はないのか!とモヤモヤしたので、自分まとめます。
自分と同じような人の為に!!(自分用のメモですすみませんw)flashメッセージの表示方法
それではレッツ実装!!
まずはコントローラーから。
コントローラー
def destroy @review = Review.find(params[:id]) @review.destroy if review.destroy redirect_to root_path, notice: "︎レビューを削除しました!" end endメッセージを表示させる記述は4行目の
if
文からです。レビューが削除された後、
root_path
(ホーム画面)に戻って
「レビューを削除しました」というメッセージが表示される。という流れです。続いてビュー画面へ!
ビュー
<% if flash[:notice] %> <div class="flash"><%= flash[:notice] %></div> <% end %> <%= yield %>flashメッセージはいろんな場面で共通で使う事が多いので、
views/layouts/application.html.erb
の<%= yield %>
より上の部分に記述します。コントローラーとビューはひとまず完成!!
JavaScriptの下準備
まずは
Gemfile
以下のコードを記述します。gem 'jquery-rails'からのターミナルで
$ bundle install
続いて
app/assets/javascripts/application.js
に以下のコードを加えましょう。//= require jqueryこれで
jQuery
の下準備完了。flashメッセージをフェードアウトさせる方法
いよいよ実装していきます。
①jsファイルに記述する場合(推奨)
以下のコードを
app/assets/javascripts/application.js(上と同じ場所)
に加えたら完成!!$(function(){ setTimeout("$('.flash').fadeOut('slow')", 2000); });②ビューファイルに直接記述する場合
以下のコードを
flashメッセージを表示させたいビューファイルに加えたら完成!!<script> $(function() { setTimeout("$('.flash').fadeOut('slow')", 2000); }); </script>※「.flash」はapplicaton.html.erbのdivに付けたクラス名です。各自自由に命名しましょう。
※数字部分は好みに合わせて変えましょう!ちなみに1000で1秒です。さいごに
今回はレビューの削除
destroy
後の実装でしたが、もちろん編集edit
や
お気に入りfavorite
なんかも実装可能です。あとはお好みで
CSS
をいじれば、
よく見るflashメッセージの完成です!!<参考>
https://qiita.com/dir_sh0606/items/b2165459deda97ae8468
- 投稿日:2020-02-12T23:10:51+09:00
【備忘録】Ruby : クラスメソッド、インスタンスメソッド使い方
sample.rbclass Person attr_accessor :from def self.lefty(name,age) #メソッド名の頭に self. をつけるとクラスメソッドになる。 new(name,age,"左") #newすることでinitializeメソッド呼び出し end class << self #複数のメソッドをクラスメソッドにする方法 def second_method puts "second" end def third_method puts "third" end end def initialize (name,age,foot) #new メソッド使った時に使用 @name = name @age = age @foot = foot end def sayHello puts "私は #{@name}です。 #{@age}歳です。 利き足は #{@foot}です。" #ここで使っている@name,@age,@sexはinitializeで定義したものを使っている。 end def sayFrom if @from != nil puts "私は #{@name}です。 #{@age}歳です。#{@from}出身です。" #ここで使っている@fromはattr_accessorの:fromに格納された値を使う。(インスタンス変数) #ちなみに @from 部分を from に書き直してもしっかり出力される else puts "私は #{@name}です。 #{@age}歳です。" end end end person1 = Person.lefty("中村",27) #クラスメソッドを使用 person1.sayHello person2 = Person.new("中田",29,"右") #単純に new #initializeメソッドの処理でインスタンス変数に引数を突っ込む person2.sayHello person3 = Person.new("小野",26,"右") #単純に new person3.from = "静岡" # さらにattr_accessor:fromに静岡をセット=>@from person3.sayHello person3.sayFrom puts person3.from #=>"静岡" #puts person3.name #=>出力エラー #解決方法=> attr_accessor に :name を追加 #追加後、=>小野 #foo = Foo.new #foo.first_method #foo.second_method #上記のようにオブジェクトを生成した後にクラスメソッドを呼び出すことは不可能出力結果
私は 中村です。 27歳です。 利き足は 左です。 私は 中田です。 29歳です。 利き足は 右です。 私は 小野です。 26歳です。 利き足は 右です。 私は 小野です。 26歳です。静岡出身です。 静岡
- 投稿日:2020-02-12T22:29:14+09:00
Mohoから出力したSVGを制御したい妄想の話
現在、実際に作ってる最中のブツがこちら。
適当なタイミングで更新をしてるので、ここで書いてる内容から構成が変わってる可能性あり。【GitHub】SourceOf0-HTML/path_control: SVGを制御したい願望
https://github.com/SourceOf0-HTML/path_control【GitHub Pages】ベクターデータをいじり倒したい気持ち
https://sourceof0-html.github.io/path_control/さて。
妄想話の前に、そもそもの話から。Mohoとは
2Dアニメーションソフトウェアのこと。
昔はAnime Studioという名前だったらしい。
自分が使用しているのはMohoPro12。2Dアニメーションソフトウェア – Moho (Anime Studio): イーフロンティア
https://www.e-frontier.com/smithmicro/moho/初めて使ってみたときに調べたことを解説動画として雑にまとめたこともある。
MohoPro12使ってみたので自己流解説 - YouTube
https://www.youtube.com/watch?v=hNsmKullIvoSVGとは
スケーラブル・ベクター・グラフィックス(Scalable Vector Graphics)の略称であり、画像形式の一種。
PNGやJPGはラスタ形式…ビットマップ画像とも言われるもので、pixel(画素)の集まりで構成されている。
ちなみにpixelはpicture cell(画像の細胞)からの造語らしいよ。
写真なんかは基本ラスタ形式。
細かい色合いを表現できるのが特徴。
拡縮すると劣化するのが弱点。これに対してSVGはベクタ形式と呼ばれる画像…
というか図形と言った方が分かりやすいかもしれない。
複数の点(アンカーポイント)を繋いだ線(セグメント)に対して、線の太さや塗りの色を設定することで画像が構成されている。
ポスターなんかは基本ベクタ形式。
拡縮しても劣化しないのが特徴。
細かい色合いを表現しようとすると、点と線の数が膨大(≒データサイズが膨大)になるのが弱点。最近のWeb上のアイコンはSVG形式のものが多い…
てか今見たらQiitaのロゴもSVGだね。MohoからSVGを出力すると…??
Mohoで作成したアニメーションは、SVGの連番ファイルとして出力することができる。
…が、しかし。バ グ る & フ ァ イ ル が 重 い 。
というところは、去年苦労した部分の話。
当時そのあたりで奮闘した話をブロマガでしてたので、そこから引用をば。【2019-03-06】「SVGでアニメーションさせたいんじゃ」の詳細報告:変人のブロマガ - ブロマガ
https://ch.nicovideo.jp/FlyingEchidna/blomaga/ar1708679実際にsvgを表示したときに、設定していた一部のマスクが効いてない。
詳しく差分データを用意してタグを解読していくと…
どうやら、マスク設定を有効にしたグループ内にグループを入れ子で置いた場合、マスク設定が出力されない模様。
mp4で出力したときは問題なかったし、Moho側のバグっぽい。オマケにタグをよく見ると、表示しているパスをそのままマスクとしても流用する設定を入れていた場合、内容が全く同じパスを表示用とマスク用として出力していることが発覚。
どうにかならんかとsvgの仕様を調べたところ、useタグを使うことでパス情報の使いまわしができることが発覚。
どうにかしてuseタグに移行させたい。…とまあそんなことがありましたとさ。
愚直にSVG連番ファイルを再生
当時、四苦八苦してRubyで
- バグで吹っ飛んだマスクを、レイヤー名(SVG側でのgタグのID)を頼りに再設定
- 同じデータを共通設定として整理しなおしてSVGを圧縮
をしまして。
出来上がったSVG連番を、JavaScriptを使ってHTML上でパラパラ漫画形式で再生、というのをやりましたとさ。【GitHub】SourceOf0-HTML/walk_anime: svgアニメーションのテスト
https://github.com/SourceOf0-HTML/walk_anime※圧縮したとはいえ、ゲロ重注意(23.1MB)
【GitHub Pages】walk
https://sourceof0-html.github.io/walk_anime/ただ、このとき書いたRubyのコードは、あまりに四苦八苦したせいか、GitHubには上げてなかったようで。
またSVGをいじるにあたり、今回のGitHubのリポジトリには入ってます。えぇ。【GitHub】path_control/addMaskTag.rb at master · SourceOf0-HTML/path_control
https://github.com/SourceOf0-HTML/path_control/blob/master/convert/addMaskTag.rbものとしては
同階層にsourceフォルダを作成&Mohoから出力したSVG連番ファイルを入れて実行すると、
同階層のdestinationフォルダに同名のSVGファイルを出力する、
というもの。
ただ、さすがに変換前後のSVGまでは重いので、フォルダも含め一緒には上げてないです。再生だけじゃなく制御したくなってきた
ここからが今年の話。
久々に衝動のままMohoでアニメーションを作っていたところ、どうにも思った動きをしない部分が出てきて、気が付いた。
「あぁ、Mohoがやってるのはボーン(動きを制御するための骨のようなもの)を
基準としたアンカーポイント周りのアフィン変換(移動拡縮回転)でしかないのか」「…ということは、
インバースキネマティクス(雑に言うと、目標点に向かって腕を伸ばすときの関節の角度の制御方法)で、
ボーンを再現した上で、SVGの制御したら…
Moho上での作業画面みたいな感じで、リアルタイムでアニメーション生成できるんじゃね?」「Moho上のアクションの合成でやるモーフィング(ある形からある形へ徐々に変形するアニメーション)も実装できたら、夢がひろがりんぐじゃね?」
「やったろ」
尚、この思い付きから、現在すでに1ヶ月経っております。えぇ。
そして、今からするのはあくまで経過報告です。
まだできてない。うん。ちなみにインバースキネマティクス自体は、p5.jsでシンプルなものを作ったことがあって、実物で言うとこんな感じ。
sketch_190830b - OpenProcessing
https://www.openprocessing.org/sketch/748924ちなみにフォーワードキネマティクス(指定した角度に関節を曲げる&次の関節にも角度が影響する)というものも存在する。
sketch_190830a - OpenProcessing
https://www.openprocessing.org/sketch/748921フォーワードキネマティクスの方がシンプルだし、処理的にもよく見かけるかも。
多分ボーンを実装するときはこっちもお世話になる。もう脱SVGしてバイナリ化しようぜ
今回やりたいことをやろうとすると、SVGの中身を参考にしつつ、どのパーツをどういう形で描画するのか制御しなきゃいけない。
つまり、SVGをそのままHTML上に表示するのではなく、JavaScriptで編集した後のものを表示しなきゃいけない。そこまでするなら、SVGを解析&座標や色・差分の情報を自分で設計したクラスにぶちこんで、canvasに描画した方がよくない??
というかそこまで解析してしまうなら、それをベースにバイナリ出力&バイナリ読み込みした方が、ファイルサイズも減るやん??
…と、いうことで。
現状、ここまでができており、冒頭に置いてるものは(2020-02-12現在)バイナリ化したものを読み込んで表示しております。
一応改めてリンク張っとこう。通信量は4.1M。
前述のが23.1MBだったことを思えば、軽い軽い。【GitHub Pages】ベクターデータをいじり倒したい気持ち
https://sourceof0-html.github.io/path_control/解説とかこれからの方針とか
作ったブツの構成は現状こんな感じ。
【GitHub】SourceOf0-HTML/path_control: SVGを制御したい願望
https://github.com/SourceOf0-HTML/path_controlファイル構成(2020-02-12現在)
ファイル・フォルダ 説明 convert/ 前述のSVG変換用のRubyとか入ってる img/ convertのヤツで変換した後のSVG連番ファイルが入ってる js/ JavaScriptファイルあれこれ(後述) src/ 独自形式バイナリファイルが入ってる BinaryStructuresNote.txt バイナリファイルの構成メモ ClassStructuresNote.txt クラスの構成メモ index.html GitHub Pagesで表示してるページ output_data.html SVG->バイナリ変換処理用HTML svg.html SVGそのまま再生用HTML jsフォルダの中身はこんな感じ
ファイル 説明 index.js index.html用 output_data.js output_data.html用 path_control.js メイン処理用 path_control.min.js メイン処理用(Minify済み) svg.js svg.html用 ちなみにMinifyってのは、ブラウザに読み込ませるJavaScriptのコードが長すぎるとデータが重くなるから、その分通信量かかるでしょ?ってことで、コードを圧縮すること。
人によってはよく「○○.min.js」ってのを見かけると思うけど、あれはそういうもの。Minify化するツールは検索したらいろいろ出てくるよ。
自分が今お世話になってるのはココ。JavaScript Minifier
https://javascript-minifier.com/htmlに対応したjs共
index.js、output_data.js、svg.js、のことね。
主にHTMLで表示しているcanvasの制御と、
path_control.jsで実装してある処理の呼び出しをしてる。
フレームレートやフレーム数を管理しつつ、描画処理命令を呼び出して…みたいな。
この辺りはまだまだ構成をいじるだろうなと思ってる。というのも、
表示したいものをループ再生させるだの、
ボーンをどう動かすかだの、
どれぐらいモーフィングさせるかだの、
再生周りの制御を最終的にすることになるので…
初期化処理のつもりで作ってるところで、そこまで面倒見てたらえらいことになるやん?なので、フレーム数処理あたりは特に、メイン処理にあたるpath_control.jsに引っ越しなりなんなりすると思う。
最終的には初期化と、マウスやスマホでの操作の入力を受け取るだけにしたい。path_control.js
メイン。本題。本体。うん。
久々にガチめのクラス設計をしてるので、クラスの説明をば。
クラス名 説明 PathCtr ファクトリー&シングルトンなクラス PathContainer 1キャラ分のデータに相当。
画像サイズや各アクションの総フレーム数、GroupObjのインスタンスをリストで持ってる。GroupObj Mohoのグループレイヤー、SVGのgタグに相当。
PathObjのインスタンスのリストや、入れ子になってるGroupObjのインスタンスのリストを持ってる。PathObj Mohoのベクターレイヤー、SVGのpathタグに相当。
実際に描画するアンカーポイントやセグメントの塗りの色情報なんかを持ってる。『ファクトリー&シングルトン』てなんやねん。
いや、あれですわ。
デザインパターンってヤツです。えぇ。ファクトリーパターンは、生成するときにしか用事がない処理をまとめて実装してある設計のこと。
生成し終わったインスタンスでやる処理と言えば、
描画前の座標更新だったり、
実際の描画処理だったりするんだけど、
生成するときの…
今回だとSVGを解析して~とかバイナリを解析して~なんて処理は、
各々のインスタンスに持たせる必要がない処理なので、
PathCtrにまとめてある。シングルトンパターンは、実行中のプログラムの中で1つしか実体(インスタンス)を用意しない設計のこと。
C++とかでガチでやるなら、外部からのコンストラクタやコピーコンストラクタの呼び出しを禁止して、別途インスタンスを生成して返すstaticの関数を作って…とかガッツリやることがあったりするけども…今回JavaScriptでやってるのは、varで用意した変数にオブジェクトを突っ込んでるだけの雑な作りです。
なので、最早クラスと呼んでいいのか怪しい。
単なるオブジェクト。うん。今後ボーンを実装するにあたり…
ボーン周りは現状まったく未着手。
その前にアフィン変換部分を実装しようかと思ってる。
ようは行列変換。そう。数学で出てくるあの行列。\begin{pmatrix} y_1 \\ y_2 \\ 1 \end{pmatrix} = \begin{pmatrix} p & q & b_1 \\ r & s & b_2 \\ 0 & 0 & 1 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ 1 \end{pmatrix}↑ こういうやつ。
数学赤点偏差値28の自分がそんな高等なことできるの?
って言われたら…
まあ…自力で全部理屈から追って実装するのはキツいかな。ただ、世の中便利なもので、そういう行列変換周りの処理をまとめて実装してあるコードは存在して、自分も実際お世話になりまくってるのよね。
描画系のプログラムを書いたことがある人なら見たことがあるかもしれない。xxx.translate(); xxx.rotate(); xxx.scale();こういう関数。ようはこれの実装だったりする。
それでいて、これの実装をしてる人は世の中に結構いるわけで。今回は ↓ を参考にさせていただいて実装して、描画前の更新処理として走らせようかなと思ふ。
【GitHub】transformation-matrix-js/matrix.js at master · leeoniya/transformation-matrix-js
https://github.com/leeoniya/transformation-matrix-js/blob/master/src/matrix.jsと、いったところで。
現状報告終了!
- 投稿日:2020-02-12T21:15:42+09:00
【備忘録】Ruby : 基本的なclass作成、定数の扱い方
sample.rbclass SampleClass attr_accessor :name,:greet # attr_accessor:name,:greetはinitializeメソッド内の # @name,@greetに関連 def initialize(name,greet) # initializeメソッド => classをnewした時に必ず呼び出される。 # メソッドの引数で受け取った値をインスタンス変数 # にセットしている。 @name=name @greet=greet end end sample = SampleClass.new("Tanaka","挨拶") # newメソッドでクラスの定数に引数を渡したので # sampleオブジェクトではname="Tanaka",greet="挨拶"が入っている。
- 投稿日:2020-02-12T20:18:07+09:00
ローカル環境にて、nokogiriが原因(?)でbundle installできないときの解決策
ローカル環境にrailsの開発環境を作ろうと以下の記事Ruby初学者のRuby On Rails 環境構築【Mac】
を参考に進めていると、以下のエラーに遭遇した。$bundle install #以下が実行結果 Fetching gem metadata from https://rubygems.org/............. Fetching gem metadata from https://rubygems.org/. Resolving dependencies... Using rake 13.0.1 Using concurrent-ruby 1.1.6 Using i18n 1.8.2 Using minitest 5.14.0 Using thread_safe 0.3.6 Using tzinfo 1.2.6 Using zeitwerk 2.2.2 Using activesupport 6.0.2.1 Using builder 3.2.4 Using erubi 1.9.0 Using mini_portile2 2.4.0 Fetching nokogiri 1.10.8 Installing nokogiri 1.10.8 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension. current directory: /Users/(user)/Desktop/Rails/vendor/bundle/ruby/2.5.0/gems/nokogiri-1.10.8/ext/nokogiri /Users/(user)/.rbenv/versions/2.5.0/bin/ruby -I /Users/(user)/.rbenv/versions/2.5.0/lib/ruby/site_ruby/2.5.0 -r ./siteconf20200212-25664-dl2tcu.rb extconf.rb --use-system-libraries checking if the C compiler accepts -I /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/libxml2... *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: --with-opt-dir --without-opt-dir --with-opt-include --without-opt-include=${opt-dir}/include --with-opt-lib --without-opt-lib=${opt-dir}/lib --with-make-prog --without-make-prog --srcdir=. --curdir --ruby=/Users/(user)/.rbenv/versions/2.5.0/bin/$(RUBY_BASE_NAME) --help --clean /Users/(user)/.rbenv/versions/2.5.0/lib/ruby/2.5.0/mkmf.rb:456:in `try_do': The compiler failed to generate an executable file. (RuntimeError) You have to install development tools first. from /Users/(user)/.rbenv/versions/2.5.0/lib/ruby/2.5.0/mkmf.rb:574:in `block in try_compile' from /Users/(user)/.rbenv/versions/2.5.0/lib/ruby/2.5.0/mkmf.rb:521:in `with_werror' from /Users/(user)/.rbenv/versions/2.5.0/lib/ruby/2.5.0/mkmf.rb:574:in `try_compile' from extconf.rb:138:in `nokogiri_try_compile' from extconf.rb:162:in `block in add_cflags' from /Users/(user)/.rbenv/versions/2.5.0/lib/ruby/2.5.0/mkmf.rb:632:in `with_cflags' from extconf.rb:161:in `add_cflags' from extconf.rb:416:in `<main>' To see why this extension failed to compile, please check the mkmf.log which can be found here: /Users/(user)/Desktop/Rails/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-18/2.5.0/nokogiri-1.10.8/mkmf.log extconf failed, exit code 1 Gem files will remain installed in /Users/(user)/Desktop/Rails/vendor/bundle/ruby/2.5.0/gems/nokogiri-1.10.8 for inspection. Results logged to /Users/(user)/Desktop/Rails/vendor/bundle/ruby/2.5.0/extensions/x86_64-darwin-18/2.5.0/nokogiri-1.10.8/gem_make.out An error occurred while installing nokogiri (1.10.8), and Bundler cannot continue. Make sure that `gem install nokogiri -v '1.10.8' --source 'https://rubygems.org/'` succeeds before bundling. In Gemfile: rails was resolved to 6.0.2.1, which depends on actioncable was resolved to 6.0.2.1, which depends on actionpack was resolved to 6.0.2.1, which depends on actionview was resolved to 6.0.2.1, which depends on rails-dom-testing was resolved to 2.0.3, which depends on nokogiriどうやらnokogiriがインストールできてないみたい..
まず、解決策
以下の記事macOSアップデート後の『xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)...』の対処法
を参考にした。以下を実行し、xcodeのツール(?)のインストールをした後、再度bundle installをしたら解決した。
$ xcode-select --installどのように解決に至ったか
エラーメッセージに
Check the mkmf.log file for more details. You may need configuration options.
と出ていたので、mkmk.logを開いた。
そこにmkmk.logxcrun: error: invalid active developer pathというエラーが出ていたので、ググったところ上記の解決につながった記事がヒットした。
- 投稿日:2020-02-12T20:09:22+09:00
Railsで検索機能を実装する場合の4つのパターン
パターン
- Ransackを使う
- コントローラーに書く
- Concernに書く
- Formオブジェクトを使う
Ransackを使う
Ransack使うとソートも楽に書けそうだけど、
追々カスタマイズが面倒そうなのもあり最初から自分で書くことが多い。
あまり使ったこと無いので、ケースによっては触ってみたい。コントローラーに書く
comments = Comment.where(post_id: params[:post_id]) if params[:post_id].present?こんな感じでコントローラーに直接where文を書くケース。
何も考えずに書くとこうなることが多いと思う。
条件式が増えてくると複雑度上がってrubocopに怒られる。Concernに書く
module Comments module SearchModule extend ActiveSupport::Concern def self.do_search(params) comments = Comment.all search_by_post_id(comments, params[:post_id]) if params[:post_id].present? end def self.search_by_post_id(comments, post_id) comments.where(post_id: params[:post_id]) end end endComments::SearchModule.do_search(params)検索用のConcernモジュールに切り分ける方法。FatControllerはこれで解消できるので良さげ。
ただConcern特有のお作法があるので、自由に書きづらく、単純なクラスが使いたくなった。Formオブジェクトを使う
class CommentSearchForm < SearchForm attribute :post_id, Types::Maybe::Coercible::Integer def do_search comments = Comment.all search_by_post_id(comments, post_id.value_or) if post_id.value_or.present? end private def search_by_post_id(comments, post_id) comments.where(post_id: post_id) end endDry::Types.load_extensions(:maybe) module Types include Dry::Types.module end class SearchForm < Dry::Struct endCommentSearchForm.new(params.to_hash.symbolize_keys).do_searchモデルに紐付かないパラメータを処理する時にはVirtusが便利で良く使われているそう。
ただ公式リポジトリをみると作者が後継ライブラリである
dry-rb
を推奨していたので、dry-rbを元に実装した。
https://github.com/solnic/virtus厳密には型指定のみなので以下の3つ。
dry-validation
でバリデーションも出来るようなので、後々使ってみたい。gem 'dry-monads' gem 'dry-struct' gem 'dry-types'普通にgemをインストールすると一番古い0.5系になるので、最新の使い方とは違うので注意。
Formオブジェクトを使ったことで、次のようなメリットがある気がする。
まだ余り使いこなせてないので詳しい方の意見聞きたい。
- フォーム関連の処理が書かれていることがひと目でわかる
- FatController対策になる
- シンプルなクラスでテスト書きやすい
- 投稿日:2020-02-12T18:51:29+09:00
Ruby の型関連の情報まとめ
Ruby のバージョン3.0から型定義・型検査ができるようになる予定なのでそのまとめ。(2020年2月12日時点)
用語一言解説
- 型シグネチャ:型定義ファイル
- 型プロファイラ:型推論 + 型シグネチャのプロトタイプ生成
- 型検査器:型シグネチャを用いた静的型検査ツール
型シグネチャ
- 型情報を定義したファイル
- Ruby3 では Ruby ソースコード本体に型情報を書かない
- 拡張子は
.rbs
- ⇨記述のための言語は Ruby ではない
- 型シグネチャをもとに後述の型検査を実行する
- Ruby3 に同梱される
レポジトリ
ruby-signature: https://github.com/ruby/ruby-signature
型プロファイラ
- 型シグネチャ無しで型検査する(レベル1型検査)
- 型エラーの可能性を指摘
- 型の推論結果を用いて型シグネチャのプロトタイプを生成する
- 型プロファイラも Ruby3 本体に同梱される予定
レポジトリ
ruby-type-profiler: https://github.com/mame/ruby-type-profiler
型検査器
- 型シグネチャを使って静的検査をする(レベル2型検査)
- 高速化は目的としておらず、エラーなどを実行前に発見することが目的
- こちらは Ruby3 には同梱されず、各々 gem をインストールして使うことになる
レポジトリ
steep: https://github.com/soutaro/steep
sorbet: https://github.com/sorbet/sorbet参考資料
- 投稿日:2020-02-12T18:35:36+09:00
【Rails】Pinterest APIで自分のアカウントのピン一覧を取得し、JSONを返すサンプルコード
はじめに
Pinterest APIを使ってみたので自分用に備忘録を残します。
今回対象とする機能は、「自分のアカウントのピン一覧を取得する」です。
公式ドキュメントはこちら※利用制限等についてはご注意下さい。
(著作権所有者の許可を得ている場合を除いて)画像を保存または改変しないこと、また Pinterest にある画像をユーザーが印刷できるようにしないこと
ピン以外のデータを保存しないこと
などなど、制限があります。
デベロッパー向けガイドライン | Pinterest Policy環境
OS: macOS Catalina 10.15.3 Ruby: 2.6.5 Rails: 6.0.2.1前提
- Access Tokenの取得方法
rails new
など最低限の下準備などは細かく触れていません。
Access Tokenの取得はこちらから
1.
net_http_module.rb
HTTPリクエストを投げる部分は分割しておきます。
今回はGETリクエストを投げるだけなので、超シンプルです。app/controllers/concerns/net_http_module.rbrequire 'active_support' module NetHttpModule extend ActiveSupport::Concern require 'net/http' def api_get(set_URL) uri = URI.parse(set_URL) response = Net::HTTP.get_response(uri) end end2.
pins_controller.rb
※事前に以下のような
Pin
モデル、コントローラーが作成済とします。$ rails g model Pin pin_id:integer pin_url:string image_url:string width:integer height: integer
$ rails g controller api/v1/pins index
app/controllers/api/v1/pins_controller.rbclass Api::V1::PinsController < ApplicationController include NetHttpModule def index # Pinterest APIのAccess Tokenはcredentialsで管理 url = "https://api.pinterest.com/v1/me/pins/?access_token=#{Rails.application.credentials.api_key[:pinterest]}&fields=id%2Cnote%2Curl%2Cimage" # NetHttpModuleで定義したapi_getメソッドを使用 response = api_get(url) # 429(リクエスト多すぎ)ならエラーメッセージを返す if response.code == "429" render json: { error: response.message }, status: response.code elsif response.code == "200" #privateで定義したメソッドを使用してDBにpin情報を保存 save_pins_and_cursor(response) # Vue.jsに返すJSONを作成する(この辺は必要に応じて変更) res = { message: response.message, pins: Pin.all.as_json, } render json: res, status: response.code else render json: { error: response.message }, status: response.code end end private def save_pins_and_cursor(response) pins = JSON.parse(response.body)['data'] # 返ってきたデータの数だけpin情報をDBに保存する pins.each do |pin| Pin.create( pin_id: pin['id'], # Pinterestが各ピンにつけている一意なID pin_url: pin['url'], # Pinterestの該当ピンに飛ぶURL image_url: pin['image']['original']['url'], # 画像が保存されているURL width: pin['image']['original']['width'], # 画像の幅 height: pin['image']['original']['height'] # 画像の高さ ) end end endあとはこれで返したJSONをフロントエンド側でゴニョゴニョすればOKです!
【便利】APIを試せるツールも公式に用意されている
こちらのリンクから、APIの各種機能を試せるAPI Explorerにアクセスできます。
GUIで使えるのは頭が疲れてるときにも優しいですね。便利。
以上です!
おわりに
最後まで読んで頂きありがとうございました
どなたかの参考になれば幸いです
参考にさせて頂いたサイト(いつもありがとうございます)
- 投稿日:2020-02-12T16:57:54+09:00
【Rails】deviseユーザーの登録日を表示する【めちゃ簡単】
Deviseのユーザー登録日を表示することに成功しました。めちゃ簡単なので、ぜひ実装してみてください。
rubyのバージョン 2.5.1 Railsのバージョン 5.2.3 手順は以下のような感じになります。
・❶:コントローラーにTime_zoneの記述
・❷:ビューにcreated_atの記述手順1:コントローラーにTime_zoneの記述
まずは表示したいビューのコントローラーに以下の記述を行います。
class UsersController < ApplicationController before_action :set_zone 〜〜〜〜省略〜〜〜〜 private def set_zone Time.zone='Tokyo' endこんな感じで、日本語表記を綺麗なものに変更します。
僕の場合だと、usersコントローラーのmember.html.erbにユーザー登録日を表示したかったので、usersコントローラーにTime_zoneを表記しました。
別にapplication_controllerでもOKだと思いますが、変なエラーが起きても嫌なので記述する場所は限定しておくのが無難。
手順2:ビューにcreated_atの記述
以下のように記述します(自分が定義した変数に合わせて記述してください)。
<div class="member-information"><%=@user.created_at.strftime("%Y年%m月%d日 ")%></div>これで実装は終わりです。
ちなみに、created_atというカラムはデフォルトでついているものですが、もしマイグレーションファイルに記述がない場合は以下を記述してくださいね。
t.timestamps null: falseそして、null: falseだとやっかいごとが起こるそうですが、僕の開発アプリだと大丈夫そうなのでnull: falseはつけています。
お疲れ様でした!!
- 投稿日:2020-02-12T14:26:36+09:00
ruby,実引数、仮引数学び
- 実引数を定義し、それに答える仮引数の値はどんなものでも構わないが、
仮引数で受け取ったメソッド内では仮引数で使った値を用いてプログラムを組み立てる。どういう事かというと、
def aaa(input) input ** 2 end bbb_input = 3 puts aaa(bbb_input) 9大概の例題はこのような形でinputに似通ったものを使っていたりするので、
実引数、仮引数の関係がとてもわかりづらい。
なので、無茶苦茶にしてみる事にした。def aaa(szxdcrftvgbsdfghdfghjdxfghldcfvgkml) bbb_input ** 2 end bbb_input = 3 puts aaa(bbb_input) 111.rb:2:in `aaa': undefined local variable or method `input' for main:Object (NameError)しかしこのままではエラーが出てしまう。
何故エラーが出るかというと、puts aaaはdef~end内で括ったメソッドを呼び出しているに過ぎないからである。
bbb_input = 3を定義し、aaa(bbb_input)とする事でaaaにbbb_input = 3を関連付けさせ、
puts aaaによってdef aaa endで定義したメソッドに仮引数を通じて値を渡し処理を実行しようとしているが、
def aaa end内では実引数が仮引数に変換されて処理をされるのでdef aaa end内の処理は、
仮引数を使って処理を記述しなければならないのである。最初は非常にわかりにくいが、この仕組みが実はとても便利なのである。
エンジニア初心者のころは数列計算のような形でしか実引数、仮引数を扱わないと思うが、
これが例えば会計アプリを作成するとなった場合、
同じ処理を使いたいが実行結果のみ変えたいとなった時に、
実引数と仮引数が同じ処理を複数作る必要はなく、
その処理を行いたいメソッドに対して実引数さえ乗っけてしまえば、
後は仮引数が自動的に実引数を仮引数に変換してくれるので複数同じ処理を書かなくて済むのである。先ほどまで記述していたコードで表すと、
def aaa(szxdcrftvgbsdfghdfghjdxfghldcfvgkml) szxdcrftvgbsdfghdfghjdxfghldcfvgkml ** 2 end bbb_input = 3 a = 4 puts aaa(bbb_input) puts aaa(a) 9 16この通り"bbb_inpput"も"a"も無事に処理が完了する。
同じ処理はメソッド一つで済むという事である。
- 投稿日:2020-02-12T13:22:45+09:00
rubyメモ
- 文字列を繋ぎ合わせる場合、+を使うことで繋ぎ合わせることが出来る。
input = "aaa" + "bbb" + "ccc" puts input "aaabbbccc"
- ""内で特定の記号で区切られた文字列を配列にし分割する。
input = "aaa;bbb;ccc;" a = input.split(';'); a.each do |a| puts a end aaa bbb ccc
- 最初の文字を大文字にし、後の文字は小文字にする。
input = "aaabbbccc".capitalize puts input Aaabbbccc
- 文字列の順番を逆に並べ替える
input = "abcde".reverse puts input edcba
- 全ての文字列を大文字で返す。
input = "abcde".upcase puts input ABCDE
- 引数で渡された文字列の二乗の数を返す。
def aaa(input) input ** 2 end bbb_input = 5 puts aaa(bbb_input) 25
- 投稿日:2020-02-12T12:35:58+09:00
Rails6 のちょい足しな新機能を試す 120(Rails.logger in Fiber編)
はじめに
Rails 6 に追加された新機能を試す第120段。 今回は、
Rails.logger in Fiber
編です。
Rails 6 (と Rails 5.2.4.1) では、Fiber の中でRails.logger.local_level
でログレベルを変更しても、それが親(Fiber の親)に影響を与えないようになっています。Ruby 2.6.5, Rails 6.0.2.1, Rails 5.2.4.1, Rails 5.2.3 で確認しました。 (Rails 6.0.0 でこの修正が入っています。)
$ rails --version Rails 6.0.2.1今回は、適切な利用例を思いつきませんでした。controller を1つ作って、
index
の中で、 Fiber を使って確認します。Rails プロジェクトを作る
Rails プロジェクトを新たに作成します。
$ rails new rails_sandbox $ cd rails_sandboxHome コントローラを作る
index
ビューを持つHome
コントローラを作成する。$ bin/rails g controller Home index
Controller を修正する
Controller を修正し、
index
の中で、Fiber を使います。Fiber#resume
を呼ぶ前後で、Rails.loggerapp/controllers/home_controller.rbclass HomeController < ApplicationController def index Rails.logger.level = 1 Rails.logger.info("[Before] Rails.logger.debug? #{Rails.logger.debug?}") Fiber.new do Rails.logger.local_level = 0 Rails.logger.info("[Fiber] Rails.logger.debug? #{Rails.logger.debug?}") end.resume Rails.logger.info("[After] Rails.logger.debug? #{Rails.logger.debug?}") end endrails server を実行して確認する
rails server
を実行し、 http://localhost:3000/home/index にアクセスすると以下のように出力されます。[Before] Rails.logger.debug? false [Fiber] Rails.logger.debug? true [After] Rails.logger.debug? falseRails 5 では
5.2.4 では、Rails 6 と同様の動作をしますが、 Rails 5.2.3 では、以下のように
Fiber#resume
実行後、元に戻りません。[Before] Rails.logger.debug? false [Fiber] Rails.logger.debug? true [After] Rails.logger.debug? trueその他
どうもよくわからない事象が1つ。
以下のように、Fiber.new
のブロックの中をRails.logger.info
からRails.logger.debug
に修正します。/app/... Fiber.new do Rails.logger.local_level = 0 Rails.logger.debug("[Fiber] Rails.logger.debug? #{Rails.logger.debug?}") end.resume ...そうするとなぜか以下のようにFiberの中のログ出力が無視されてしまいました。
Rails.logger.debug?
がtrue
になるので、Rails.logger.debug
でも出力されるかと思ったのですが...[Before] Rails.logger.debug? false [After] Rails.logger.debug? false試したソース
https://github.com/suketa/rails_sandbox/tree/try120_logger_in_fiber
参考情報
- 投稿日:2020-02-12T12:27:30+09:00
railsアプリをHerokuにデプロイ
Cloud9から作成したrailsアプリをHerokuにデプロイする際に
色々と躓いたので成功した手順を書き留めておきます。1.Herokuアカウント作成
以下のURLからHerokuアカウントを作成します。
https://jp.heroku.com/無料プランでも月550時間の稼働時間が利用できます。
利用が想定されるユーザの規模が非常に小さい場合は無料プランで十分だと思います。2.Herokuにアプリを作成
Herokuにログイン
$ Heroku loginプロジェクトフォルダに移動し、Herokuにrailsアプリを作成
$ Heroku create アプリ名3.Heroku用の設定
以下のようにGemfileに追加
group :production do gem 'pg', '0.20.0' end以下のようにproduction:内の記述を変更
config/database.ymlproduction: adapter: postgresql encoding: unicode pool: 5 database: フォルダ名_production username: フォルダ名 password: <%= ENV['フォルダ名_DATABASE_PASSWORD'] %>4.アプリをデプロイ
デプロイを実行
$ git push heroku masterマイグレーションを実行
$ Heroku run rails db:migrate5.うまくいかない時
エラーが出る場合は3のherokuの設定もしくはGitでコミットできているかを確認してください。
それでもエラーが出る場合は下の項目を実行してみてください。
修正後はマイグレーションを実行しましょう。PostgreSQL アドオンの追加
PostgreSQLのインストールができてない可能性があるため、手動でアドオンを追加します。
$ heroku addons:create heroku-postgresql:hobby-dev環境変数の確認
実行に必要な環境変数が空になっている可能性があります。
configでそれぞれの環境変数に値が入っているかを確認してください。$ heroku config値が空だった場合は以下のコマンドで環境変数に値を入れます。
$ heroku config:set HENSU=hensuエラーログ参照
以下のコマンドでログを確認すれば、エラーの詳細がわかります。
$ heroku logsリアルタイムで出力したいなら以下のコマンド
$ heroku logs --tail画像アップローダー
もし画像アップロード機能を実装している場合はローカルではなく
クラウド上にファイルが保存されるように設定を行う必要があります。
設定はこのあたりの記事が参考になりました。
https://qiita.com/junara/items/1899f23c091bcee3b058
https://qiita.com/daichi41/items/af2a56ea46c13ca55fd3
https://qiita.com/hmmrjn/items/479c9e9ce82771f1b6d7
https://pg-happy.jp/rails-aws-s3-upload.html
- 投稿日:2020-02-12T06:39:44+09:00
【環境構築】Rails6 + Vue.jsで hello_vue.jsの名前をmain.jsに変更したいときの手順
はじめに
先日、こちらの記事を書きました。
【環境構築】Docker + Rails6 + Vue.js + Vuetifyの環境構築手順 - Qiitaそこで自動生成される、
app/javascript/hello_vue.js
の名前をmain.js
に変更したい方のために手順を記載しておきます。(対象が狭い!笑)環境
OS: macOS Catalina 10.15.3 Ruby: 2.6.5 Rails: 6.0.2.1 Docker: 19.03.5 docker-compose: 1.24.1 Vue: 2.6.10 vuetify: 2.1.0前提
こちらの記事に沿って環境構築が完了したとします。
1.ファイル名を変更
app/javascript/packs/hello_vue.js
の名前を変更します。
hello_vue.js
↓
main.js
2.home/index.html/erbを変更
app/views/home/index.html.erb<%= javascript_pack_tag 'hello_vue' %> <%= stylesheet_pack_tag 'hello_vue' %>app/views/home/index.html.erb<%= javascript_pack_tag 'main' %> <%= stylesheet_pack_tag 'main' %>3.
manifest.json
内を変更最後に、Webpackが出力した
manifest.json
をいじる必要があります。public/packs/manifest.json{ // 略 "entrypoints": { // 略 "hello_vue": { "js": [ "/packs/js/hello_vue-343ebbfc5aed29c10bf6.js" ], "js.map": [ "/packs/js/hello_vue-343ebbfc5aed29c10bf6.js.map" ] }, // 略 }, "hello_vue.js": "/packs/js/hello_vue-343ebbfc5aed29c10bf6.js", "hello_vue.js.map": "/packs/js/hello_vue-343ebbfc5aed29c10bf6.js.map", // 略 }↓
public/packs/manifest.json{ // 略 "entrypoints": { // 略 "main": { "js": [ "/packs/js/main-343ebbfc5aed29c10bf6.js" ], "js.map": [ "/packs/js/main-343ebbfc5aed29c10bf6.js.map" ] }, // 略 }, "main.js": "/packs/js/main-343ebbfc5aed29c10bf6.js", "main.js.map": "/packs/js/main-343ebbfc5aed29c10bf6.js.map", // 略 }以上です!
おわりに
最後まで読んで頂きありがとうございました
どなたかの参考になれば幸いです
前回の記事
- 投稿日:2020-02-12T02:28:29+09:00
自動デプロイ後ローカルでいろいろ変更してデプロイしたらmigrationとunicornで詰まりデプロイできなかったので解決までの備忘録
自動デプロイでかなり詰まったので備忘録として残します。
- 初学者のため理解が不足しているところがあり、解決の過程で必要のない工程をしている可能性があります。
- もし他の改善策などご指摘いただけることがあればよろしくお願いしたします。
エラー過程①
- 自動デプロイ完了後ローカルでデータベース構成などを変更
- 変更後自動デプロイ実行する。
- 途中でmigrationの実行で止る。
解決までの流れ①
原因の仮説としてはローカルでデータベースのテーブルやカラムの変更を行いrails db:migrate:resetを行ったためだと仮定し本番のデータベースもリセットすることにした。
関連の記事を探し、こちらで書かれているコードを参照、一度データベースを消してしまうという方法を取ってみたhttps://qiita.com/wacker8818/items/72d933f036ca0b75d124
無事データベースは削除され、改めてデータベースの作成とマイグレーションを実行したが落とし穴に会う。
- ローカルに戻りアプリケーションのディレクトリで、自動デプロイを実行したがまたもマイグレーションの実行部分でエラーが起きた。
- 何故かなと思ったが、エラー内容としては、マイグレーションファイル読み込み時に、追加したいカラムがもうあるよ的なエラーでした。 - 理由は本番でデータベース削除の後にマイグレーションまで実行してしまったことだった。 - 考えてみれば当たり前の話なのだが、この時点ではまだ修正したマイグレーションファイルも反映していないので、古いマイグレーションファイルをマイグレートして、さらにローカルで新しいマイグレーションの読み込みを実行していたのだ。 - なのでもし修正した方のマイグレーションファイルに、前に作ったマイグレーションファイルの設定と同じ記述があればエラーが起きるのは当たり前になる。
なのでもう一度データベースを消してやり直ししてなんとかマイグレーションの自動デプロイは通った。
エラー過程②
- ①通過後unicornstartでエラー発生し止る。
解決までの流れ②
ターミナルmaster failed to start, check stderr log for details # エラー文
- エラー文を参考に調べた結果
- このエラーの原因解決には(おそらく)本番環境でunicornのログを見てみるのが一番の近道らしいと聞いたので見てみる。
- 何個かエラーらしきところは確認でき、どこのファイルのどこの行かまで詳しくログに書いてあったが簡単な記述ミスが起きているでけということで特にunicornが動かない原因だと考えなかった。
- その後unicornのプロセスで見えないプロセスが裏で動いている可能性があると、指摘を受け調べてみたがその裏で動くプロセスの見方がわからなかった。
- 詳しい方にいろいろ聞き本番環境のアプリケーションのディレクトリで下記のコマンドを実行。
ec2-user(appディレクトリ)sudo vim shared/tmp/pids/unicorn.pid
vimファイルの一番上にpid番号らしき5桁の番号が保存されていたため直接消去しvimファイルを保存。
- もう一度vimファイルを開いてちゃんと保存されているか確認。
- これで解決できたと思いローカルに戻り自動デプロイを実行。
- しかしまた同じunicorn実行の部分でエラーが起きた。
ここでもう原因がわからず悩んだが、一番エラーの原因として可能性が低いと思っていた、以前unicornログで見たエラーを解決することを優先。
- ここでのエラーはcontrollerでメソッド定義したときのendの数が足りなかったという単純なものだった。
- その後ダメ元で自動デプロイを実行したらなんと通った!!
unicornで止る原因(仮説)
- ローカルでエラーがあるものをmasterにmergeしてそのまま自動デプロイをするとエラーで止る。(特にデータベース、コントローラー関連のところ)
- 不要なプロセスが動いている。(killコマンドでプロセスを消す必要がある。)
- 途中で強制的にpidの接続が切れた場合、裏でも動いている可能性がある.
反省
- 一度マイグレーションしたデータベースのテーブルやカラムの変更を行う際は、しっかりと直接記述せずターミナルのコマンドで追加、または削除すること。
- 自動デプロイがしっかり完了したら基本的にエラーの原因はローカルでの変更が原因なので、実装と動作確認をしっかり行うこと。
• この記事を書いてみての反省
書く時はエラー文をしっかりコピーなどして参照しやすいようにしたほうがわかりやすく書くことができたと思う。
長々と文章ばかりでわかりづらいところが多いので、端的にもっと説明できるように文章力も磨いていく。
拙い文章を最後まで見てくださった方ありがとうございました。
これからも精進していきます。