Madogiwa Blog

主に技術系の学習メモに使っていきます。

railsの勉強のためのTwitterBotをリリースしました📢

f:id:madogiwa0124:20181111222201p:plain

みなさん、こんばんは。まどぎわです(・∀・)
本日、Rails勉強BotというTwitterBotをリリースしました!🎊
railsを勉強している人には役に立つと思うので、この記事で使い方など紹介します📢✨

rails勉強Botとは?

rails勉強Botは、railsのメソッドとGithub上のソースコードへのリンクを投稿するTwitterBotです🐦
現在は、10分に一回ActiveSupportのメソッドについて呟いてくれています📢

twitter.com

rails勉強Botの活用方法

rails勉強botをフォローすると10分に一回タイムラインに、こんな感じで投稿がされます✍

urlのリンクをクリックするとGithub上のソースコードを確認できます🙌 f:id:madogiwa0124:20181111220631g:plain

メソッドと実際のコードを関連付けて知ることで、より深く処理の中身を知ることが出来るんじゃないかなぁと思ってます👀

どうやって作ってるの?

APIモードのrailsとherokuを使って作っています🔨
ソースコードGithub上に公開してますので、よろしければ見てみてください🐾 github.com

そんなに難しいことはしてなくて仕組みとしては、こんな感じです。

  • public_methodsでpublicなmethodの一覧を取得
  • source_locationで該当methodが記載されたファイルとその行番号を取得
  • Github上のURLに合わせて、取得結果を整形
  • TwitterApiに作成したクラスとメソッドとGithub上のURLの文字列を渡す

👇実際に上記を行っているコードです。
rails_study_bot/active_support.rb at master · Madogiwa0124/rails_study_bot · GitHub

そもそものTwitterBotの作り方は、この辺を参考にしてもらえれば🙌

madogiwa0124.hatenablog.com

おわりに

まだActiveSupportのメソッドしか呟けていないのですが、今後はActiveRecordActionView等、対応クラスを増やして行く予定です💪
自分でも使っていますが、なかなか勉強になることも多いのでrails勉強中の方は、使ってみて感想等頂けると嬉しいです😊

PS. TwitterAPIの承認申請めんどくさすぎた😇

twitter.com

RubyOnRails:FormObjectを使って複雑なフォームの処理を良い感じに実装するメモ✍

みなさん、こんにちは!まどぎわです(・∀・)
今回は、Railsデザインパターン(?)の一つのFormObjectについて学んだので、使い方とかをメモしておきます✍

FormObjectってなに?

FormObjectとは、ActiveModelincludeしたClassにフォームで扱うプロパティをもたせたものです。

私は実際に使ってみて、下記のようなメリットを感じました!!

  • 複数モデルにまたがったバリデーション等、記載に箇所に迷う実装をスッキリ書ける。
  • Controller側の実装がスッキリして、コードの見通しがよくなる。

ちょっと、具体的な例と合わせて見ていこうと思います👀

FormObjectってどういうときに使う?

例えば、タイトルと本文とタグ(10件まで)登録するブログサービスのようなものがあったとします。
Blogに紐づくTagの個数チェックや、タグを含めたブログの登録処理等、実装箇所に迷う部分が多かったですが下記のような実装(イメージ)としてみました。。。

この状態ではコントローラーの中にエラーチェックがあったり、タグのインスタンスを作る処理があったり、トランザクションを貼って複数モデルにまたがった作成処理を行っていたり等、見通しが悪く、またコントローラーに書きたくないような処理があって、ごちゃちゃしているように感じますね(;・∀・)

class BlogsController < ApplicationController
  TAGS_LIMIT = 10
  
  def create
    @post = BlogPost.new(blog_post_form)
    ActiveRecord.transaction do
      check_up_to_limit_tags_can_be_set!
      blog = Blog.create!(title: blog_params[:title], body: blog_params[:body])
      build_tags.each do |tag|
        tag.save!
        Tagging.create!(blog: blog, tag: tag)
      end
    end
    redirect_to blogs_path
  rescue ActiveRecord::RecordInvalid
    render :new
  end

  private
  
  def check_up_to_limit_tags_can_be_set!
    return if tags.length <= TAGS_LIMIT
    @post.errors.add(:tags, 'は、10個まで設定可能です。')
  end
  
  def build_tags
    blog_params[:tags].map { |tag| Tag.new(name: tag) }
  end
end

複数モデルにまたがったエラーチェックやモデルの生成等、ちょっと複雑な機能だと結構ありがちで、実装を迷う部分な気がするのですが、こういうときにFormObjectを使うと結構スッキリかけます🙌

FormObjectを使ってリファクタリングしてみる

先程話した例をFormObjectを使ってリファクタリングしてみると下記のような感じになります!!
BlogPostFormに実装に迷った処理が集約されて、コントローラー内もスッキリし、フォーム側に登録処理を寄せることで、複数モデルの登録も違和感無い形になっているので良さそうに見えますね👀✨

class BlogsController< ApplicationController
  def create
    @post = BlogPostForm.new(blog_params)
    post.save!
    redirect_to blogs_path
  rescue ActiveRecord::RecordInvalid
    render :new
  end
end

class BlogPostForm
  TAGS_LIMIT = 10
  include ActiveModel::Model
  attr_accessor :title, :body, :tags
  validates :title, :body, presence: true
  valudate :up_to_10_tags_can_be_set
  
  def save!
    raise ActiveRecord::RecordInvalid if invalid?
    ActiveRecord.transaction do
      blog = Blog.create!(title: title, body: body)
      build_tags.each do |tag|
        tag.save!
        Tagging.create!(blog: blog, tag: tag)
      end
    end
  end
  
  private
  
  def build_tags
    tags.map { |tag| Tag.new(name: tag) }
  end
    
  def up_to_limit_tags_can_be_set
    return if tags.length <= TAGS_LIMIT
    errors.add(:tags, 'は、10個まで設定可能です。')
  end
end

FormObjectをもっと知る

FormObjectについて、すごく分かりやすく記載されてる記事です👀
※多大に参考にさせて頂きました・・・!🙇‍♂️

tech.medpeer.co.jp

FormObjectのためのGemもあるみたいです👀

github.com

おわりに

今回はFormObjectについて、少し整理してみました。
このようなデザインパターンのような知識を学ぶと自分の実装の引き出しが増える感じがして良いですね🙌
これからも学んでいきたみが強い・・・!!

【Ruby on Rails】Rails GuidesにPRを出して、Railsのコントリビューターになったよって話

はじめに

みなさん、こんにちは、まどぎわです(・∀・)
この前Railsのコントリビューターになりました!🎉

実際にマージされたのが下記PRです🙋

github.com

内容としては、Rails Guidesを1文字修正しただけなのですが😅

# bofore
If it says something like "Rails 5.1.1", you are ready to continue.
# after
If it says something like "Rails 5.2.1", you are ready to continue.

それでもRails Contributorsに名前が乗るのは、嬉しいですね🙌

contributors.rubyonrails.org

RailsのPRを見てると機能追加だけじゃなくて、docfix typoが、結構Mergeされているみたいなので、PRチャンスは結構ありそうだなと思いました👀

[ci skip] Fix typo by frodsan · Pull Request #34119 · rails/rails · GitHub

fix broken link in Action Cable guides and readme [ci skip] by gregmolnar · Pull Request #34126 · rails/rails · GitHub

Rails GuidesにPRを出すまで

というわけでRails GuidesにPRを出すまでの手順とかまとめておきます📝
手順は下記の通りです。

  1. RailsをFork
  2. Forkした自分のリポジトリguides/source配下を修正
  3. RailsのmasterにPRを出す

詳しいやり方とか注意事項は、Rails Guidesの下記ページに記載されているので、読んでみてください👀

Contributing to Ruby on Rails — Ruby on Rails Guides

https://guides.rubyonrails.org/ruby_on_rails_guides_guidelines.html

おわりに

RailsGuidesを読みながら、気づいたところをPR出すようなことやると英語とRailsの勉強にもなるし良さそうですね✨
今回出したPRの1行の英文を書くのにもだいぶ時間がかかってしまったので、英語も勉強しないといけないなと。。。

今回は、Rails GuidesのしょぼいPRでしたが、いずれは機能追加系のPRも出せるように勉強していきたいですね💪

herokuとrubyでゴミ出しを通知するLINE BOTを作ってみた🔔

みなさんこんにちは、まどぎわです(・∀・)
今回は、いつも忘れてしまっていたので、毎日明日出せるゴミを通知してくれるLINE BOT作ってみました🙌

f:id:madogiwa0124:20180930232656p:plain

やってみたら意外と簡単に出来たので手順等をメモしておきます📝

LineBotの作り方

流れは下記のような感じです👇

  1. LineDevelopersに登録
  2. チャンネル作成
  3. BOTを実装
  4. herokuにアプリを作成

LineDevelopersに登録

下記からLineDevelopersに登録できます👀

LINE Developers

f:id:madogiwa0124:20180930232920p:plain

画面に従って行って貰えれば、特に躓くところは無いと思います。

チャンネル作成

BOTを作成するには、まずはチャンネルを作る必要があります。
チャンネルとは、実際にBOTを運用するにあって必要な情報、Tokenや表示する名前等を登録します。詳しいやり方は、まとめてくださっている方がいらっしゃいますので、下記等を参考にしてみてください👇

qiita.com

BOTを実装

今回は、sinatraと公式のgemline-bot-sdk-rubyを使って作成しました。 軽く動かすだけだったら、公式チュートリアルをコピペするとオウム返しのLineBotが作成出来ます🐦

github.com

私のBotの返信処理は下記の通りです👇
メッセージが来たら、明日がなんのゴミの日かを取得し返信しています。

app.rb

post '/callback' do
  // リクエストボディの取得
  body = request.body.read

  // リクエストのチェック
  signature = request.env['HTTP_X_LINE_SIGNATURE']
  unless client.validate_signature(body, signature)
    error 400 do 'Bad Request' end
  end

  // リクエストボディをパース
  events = client.parse_events_from(body)
  events.each do |event|
    // メッセージを受信したら
    case event
    when Line::Bot::Event::Message
      // 通知メッセージを返信する
      client.reply(event['replyToken'], GomiChecker.notice_message)
    end
  end
end

ちなみに、返信等のcallbackを受けずにBOT側から通知を送信する場合は、下記のような実装になります。※ユーザーIDを指定して通知を行う必要があるので、環境変数で管理するようにしてます。

batch.rb

def push_ids
  ENV['PUSH_TO_ID'].split(',')
end

begin
  // 環境変数に設定されたすべてのユーザーに通知を送信
  push_ids.each { |id| client.push(id, GomiChecker.notice_message) }
rescue => e
  puts "batch exec error ..."
  p e
end

詳しい実装はGithubにコードを上げているので、そちらをご確認ください。

github.com

herokuにアプリを作成してデプロイ

下記のような感じでherokuにデプロイすると実際にLINEBOTが動き出すと思います🙌

$ heroku create
# hoge.gitは自分のアプリに合わせて変える
$ git remote add heroku https://git.heroku.com/hoge.git
$ git push heroku master

これでLINEから自分のBOTを友達登録して、通知を受け取れるはずです!🔔

おわりに

今回は、いつも忘れる明日のゴミの日を通知するBOTを作ってみました、実際に自分の生活を豊かにするアプリは良いですね🏠 LINEBOTを使うのは初めてでしたが結構簡単に作れたので、また何か日常で困ったことがあったら使ってみようかなと思いました🙌

Ionic:Dockerでionic開発環境を作る🐳

こんにちは、まどぎわです(・∀・)
最近またionicを触りはじめて、環境構築する際にローカルではなく、 Dockerを使ってみたのでそのやり方をメモしておきますφ(・

ちなみに私の環境は、下記の通りです。

種類 バージョン
OS MacOS High Sierra 10.13.6
Docker 18.06.1-ce-mac73 (26764)

やり方は結構簡単です🙌

まずはDockerHubでionic用のコンテナを探します🐳

https://hub.docker.com/

いろいろ出てきますが、私は下記を使いました👀

https://hub.docker.com/r/beevelop/ionic/

これを使って下記のようなDockerfileを作りました。

FROM beevelop/ionic:latest
ENV WORK_DIR /work
RUN mkdir ${WORK_DIR}
WORKDIR ${WORK_DIR}

※やってることは作業用のディレクトリを作って、そこをWORKDIRにしているだけです。

このDockerfileを任意のディレクトリに配置して下記を実行します🐳 そうするとコンテナ上の/workに作業用ディレクトリがマウントされて、ionicの開発環境が立ち上がります。

# ionic-workはコンテナ名なので、任意の名前に変える
$ docker build -t ionic-work .
# `/Users/user_name/Documents/repo/ionic/work`は適宜変える
# デフォルトのionicアプリ起動時のポート番号(8100)にアクセスできるように`-p`でホストの8100を割り当て
$ docker run -v /Users/user_name/Documents/repo/ionic/work:/work -p 8100:8100 -d -it --name ionic-work ionic-work
$ docker exec -it ionic-work bash

これでDockerコンテナ上の開発環境に接続することが出来ました🙌

アプリを作成して、下記を実行すれば、、、

$ cd アプリのルートディレクトリ
$ ionic serve

http://localhost:8100/をブラウザで開くとアプリが起動しているはずです👀
結構簡単ですね🙌

Dockerコンテナで開発環境が作れると、作成と破棄が簡単に出来るので良いですね。みなさんもIonic環境を作るときは試してみてくださいm( )m

参考

qiita.com

Vue.js: 異なるVueインスタンスのdataの値を取得する方法

下記のような2つのVueインスタンスあり、別のVueインスタンスのdataの値を参照したいときに少しハマったので、ちょっとバッドプラクティス感ありますが対応方法をメモメモφ(・

結論としては、下記のようにすればできた🙌
参照したいVueインスタンスを変数に入れといて、その変数からdataを参照して返却するメソッドを定義してあげれば良いみたい👀

let hoge = new Vue({
  el: '#hoge',
  data: {
    val1: 'val1',
    val2: 'val2'
  }
})

let fuga = new Vue({
  el: '#fuga',
  data: {
   val3: 'val3'
  },
  methods: {
    hogeVal1: function () {
      // hogeのval1をfugaで参照出来る
      retuern hoge.val1
    }   
  }
})
<div id="fuga">
  <span>{{hogeVal1()}}</span>
</div>

なんかもうちょっと良いやり方ありそうですが、とりあえず出来たので書いてみました(;・∀・)

bashでgitのコマンドのtab補完を有効にする方法

みなさん、こんにちは。まどぎわです(・∀・) 最近bashを使ってfishを使って、またbashに戻ってきました。いろいろ調べてみると結構bashでもいろいろ出来るみたいですね👀

bashだとMacのデフォルトで入ってるし、いろいろ出来るのであれば環境構築が要らないbashを使えると良いですよねということで、 今日はbashでgitコマンドの補完が、すごい簡単に出来るので、そのやり方をメモしておきますφ(・

やりかた

まず、gitコマンドの補完にはgit-completion.bashが必要です、おそらくデフォルトで入っているとおもうので、下記コマンドでファイルのパスを確認しておきます。

$ find / -name "git-completion.bash"
=> /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash

その後.bashrcに書きを追記します。

source /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash

そうすると、こんな感じでtab補完が使えるようになります。 f:id:madogiwa0124:20180901175057g:plain
※変わらない場合は、source ~/.bashrcを実行してみてください。

以上です、めっちゃ簡単ですね🙌

参考

qiita.com