神戸.rb Meetup #11 に参加したよヘ(^o^)ノ
Kobe.rbに参加してきたよヘ(^o^)ノ
今日のおやつ!! photo by @spring_aki
おいしかった♪
今日、僕が調べてたのはActiveDecorator + Capybara + RSpecです。
ActiveDecoratorでhelperを良く使いますよねー
例えばこんなの...
def full_name content_tag :td do "#{first_name} #{last_name}" end end
Decoratorが自動生成するRSpecはこちら
describe UserDecorator let(:user) { User.new.extend UserDecorator } subject { user } it { should be_a User } [...] end
毎回extendするのもアレなので、ActiveDecorator::RSpecを使います
# Gemfile gem 'active_decorator-rspec' # spec/decorator/user_decorator_spec.rb describe UserDecorator # FactoryGirlでテストデータ作成 let(:user) { build(:user) } subject { decorate user } it { should be_a User } [...] end
いい感じですねー
キモのfull_nameメソッドをCapybaraでテストしてみましょう
describe UserDecorator [..] it 'has a tr tag and full_name' do expect(subject.name).to have_content(:td, "#{user.first_name} #{user.last_name}") end end
実行すると怒られます。。。
undefined method 'content_tag' for ...
type: :heler
or type: :view
を指定すればhelperメソッドが認識されますが、
こんどはCapybaraにおこられます( ̄▽ ̄;)
have_contentはCapybara::RSpecMatchersで定義されてるのでincludeしてみます
describe UserDecorator include Capybara::RSpecMatchers let(:user) { build(:user) } subject { decorate user } it { should be_a User } it 'has a tr tag' do expect(subject.name).to have_content(:td) end end
これでテストを実行すればパスしますが、毎回includeはアレなのでrails_helperに追記
# spec/rails_helper.rb RSpec.configure do |config| config.include Capybara::RSpecMatchers, type: :decorator end
describe UserDecorator let(:user) { build(:user) } subject { decorate user } it { should be_a User } it 'has a tr tag', type: :decorator do expect(subject.name).to have_content(:td, "#{user.first_name} #{user.last_name}") end end
これでCapybaraを使ってテストできますねー
Happy Hacking٩( ‘ω’ )و
Rails - ActiveDecoratorのコード読んでみたヘ(^o^)ノ
いつもお世話になります。ActiveDecoratorさま。
@izumin5210さんの「ActiveDecorator読んでみたら超勉強になった」を読んで、そういやコードあんま見てなかったので読んでみた
なるほど編
alias_method_chain 既存のメソッドを拡張するときにちょー便利♪
コードよむ編
# lib/active_decorator/monkey/abstract_controller/rendering.rb module AbstractController module Rendering # to_aメソッドのエイリアス↓ def view_assigns_with_decorator # 既存のto_aメソッドをコール hash = view_assigns_without_decorator # メソッドを拡張 hash.values.each do |v| ActiveDecorator::Decorator.instance.decorate v end hash end # :view_assigns => :view_assigns_with_decorator # :view_assigns_without_decorator => :view_assigns alias_method_chain :view_assigns, :decorator end end
view_assignsは、Controllerで取得したインスタンスなんかが格納されたHashを返しますよー
こんな感じ↓
postsはActiveRecord::Relation
です(Post.allしたやつ)
testはインスタンス変数に文字列をいれてみた
このHashをActiveDecorator::Decorator
へ
# lib/active_decorator/decorator.rb module ActiveDecorator class Decorator include Singleton def initialize @@decorators = {} end def decorate(obj) [...] end [...] end end
singletonをMix-inしてるので、ActiveDecorator::Decorator.instance.decorate
で呼び出してますよ
decorateメソッド
if obj.is_a?(Array) # *2でArrayが引数となるのでここ # Arrayの要素(ModelClass)を引数として自身を呼び出してる *3 obj.each do |r| decorate r end elsif defined?(ActiveRecord) && obj.is_a?(ActiveRecord::Relation) && !obj.respond_to?(:to_a_with_decorator) # ActiveRecord::Relationならクラスを再オープンしてメソッド定義してる *1 class << obj def to_a_with_decorator to_a_without_decorator.tap do |arr| # Arrayを引数として自身を呼び出してる *2 ActiveDecorator::Decorator.instance.decorate arr end end alias_method_chain :to_a, :decorator end else # *3で引数がmodelクラスとなるのでここ(ActiveRecord::Relation、Array以外もここ) # decoratorのクラス取得してる d = decorator_for obj.class return obj unless d # PostDecoratorモジュールに属してなければextendしてる obj.extend d unless obj.is_a? d end
decorator_forメソッド
private def decorator_for(model_class) return @@decorators[model_class] if @@decorators.has_key? model_class decorator_name = "#{model_class.name}Decorator" d = decorator_name.constantize unless Class === d d.send :include, ActiveDecorator::Helpers @@decorators[model_class] = d else @@decorators[model_class] = nil end rescue NameError @@decorators[model_class] = nil end
ViewContextをごっそり
# lib/active_decorator/view_context.rb module Filter extend ActiveSupport::Concern included do before_filter do |controller| ActiveDecorator::ViewContext.current = controller.view_context end end end
helperの拡張
# lib/active_decorator/helpers.rb module Helpers def method_missing(method, *args, &block) super #TODO need to make sure who raised the error? rescue NoMethodError, NameError => original_error begin # helperでmethod_missingならActiveDecorator::ViewContextから(なければoriginal_errorの例外発生 ActiveDecorator::ViewContext.current.send method, *args, &block rescue NoMethodError, NameError raise original_error end end end
ViewContextをごっそりとってるから、flashとかもdecoratorで使えるよー
ActiveDecorator::ViewContext.current.flash => #<ActionDispatch::Flash::FlashHash:0x007fda40e27d78 @discard=#<Set: {}>, @flashes={"error"=>"test error"}, @now=nil> ActiveDecorator::ViewContext.current.flash[:error] => "test error" # app/decorators/post_decorator.rb module PostDecorator def error_flash flash[:error] end end
ActiveDecoratorだと読みやすくて勉強にも良いかと思います♪
Happy Hacking٩( ‘ω’ )و
d(゚Д゚ )☆スペシャルサンクス☆( ゚Д゚)b
神戸.rb Meetup #10に行ってきたよヘ(^o^)ノ
今日は神戸.rb Meetup #10に行ってきた。
仕事が押して1時間ほど遅れてしまったけど。。。( ̄▽ ̄;)
みんながそれぞれ興味あることをワイワイ話したり、もくもくしたりと良い感じです。
おやつもあるっ!!!
僕はcocoon(こくーん?)ってgemを使ってみました。
ユーザーストリーにタスクをポンポン追加していくときに使うー
使い方はとても簡単
application.jsに追加
//= require cocoon
- fields_forを使って子モデルを追加したりできるようにする
%h3 Tasks #tasks .field = f.fields_for :tasks do |task| = render 'task_fields', f: task .links = link_to_add_association f, :tasks do = icon('plus-square fa-2x') .actions = f.submit 'Save' # _task_fields.html.haml .nested-fields .field = f.label :name = f.text_field :name = f.label :description = f.text_field :description = link_to_remove_association f do = icon('times fa-2x')
10分くらいでできたサンプルがコレ
そして懇親会♪
神戸ヴァイツェン #koberb pic.twitter.com/zDeAYbm9w9
— カニ (@kanizmb) 2015, 1月 6
ゆりえちゃんのお話もできたしー.。oO(かわいい)
みなさんお疲れ様でしたヘ(^o^)ノ
Rails - ActiveModel::Callbacksでカスタムコールバックヘ(^o^)ノ
あけましておめでとうございます。
年内で仕事が納まらず、1日からコードをごりごり書いております。。。
さて、ActiveRecord::Callbacksはみなさんおなじみ
before_saveとか良く使いますよね?
でも、今回やりたい事はこういうの
# app/models/comment.rb class Comment < ActiveRecord::Base after_publish :send_mail #publishメソッドのCallback def publish [...] end private def send_mail Notifier.comment_published(self).deliver_now end end
ActiveRecordのCallbacksを参考に => active_record/callbacks.rb
# app/models/concerns/comment_callbacks.rb module CommentCallbacks extend ActiveModel::Callbacks extend ActiveSupport::Concern included do define_model_callbacks :publish, only: :after end private def action_after_publish puts '- after publish' end end # app/models/comment.rb class Comment < ActiveRecord::Base include CommentCallbacks after_publish :action_after_publish def publish run_callbacks :publish do puts '> publish!' end end end
$ Comment.new.publish > publish! - after publish
ちゃんとCallbackされましたね
もっと良い実装があれば教えてくだされー
そもそも、この実装が良いのかもわからんし...( ̄▽ ̄;)
Happy Hacking٩( ‘ω’ )و
Shinosaka.rb #11を開催したよーヘ(^o^)ノ
今年最後のShinosaka.rbを開催しましたー
みなさんのおかげで1年を通して開催することができました。
来年からShinosaka.rbはLTタイムをつくるよー
参加者のなぜ???やRubyに関する困りごとをLTしてもらって、みんなで解決していく感じです。
もちろんペアプロ大会なんかも開催する予定です。
さて、本日のテーマは「Rails 4 Patterns」でした。
スライドはこれ⇒Rails 4 Patterns
僕なりにRailsで開発するときの大事な部分を説明しました。
みんなの意見が聞けてとても勉強になったよ
スライドの最後にでてくる内部リンクのURLを生成するにはこんな感じです
post_path @post, anchor: "post_#{@post.id}"
@ogomrさんと@toshima66さんが発表してくれました
@ogomrさんはRails Tree Cheat Sheetについての発表
発表内容
- Railsのファイル構造の規約
- 最近のお気に入りgem (GitHub - vcrやGitHub - foreman)
発表後にShinosaka.rbでgemが誕生する瞬間をみた!⇒cassette-rack
僕も興味ある分野なので、一緒に開発できればと思っていますよ@ogomrさん!w
@toshima66さんはSVG(Scalable Vector Graphics)についての発表
発表内容
- 作者: Rubyサポーターズ,すがわらまさのり,寺田玄太郎,三村益隆,近藤宇智朗,橋立友宏,関口亮一
- 出版社/メーカー: 技術評論社
- 発売日: 2013/08/10
- メディア: 大型本
- この商品を含むブログ (16件) を見る
Ruby on Rails 4 アプリケーションプログラミング
- 作者: 山田祥寛
- 出版社/メーカー: 技術評論社
- 発売日: 2014/04/11
- メディア: 大型本
- この商品を含むブログ (2件) を見る
そして勉強会より楽しいと噂の懇親会へw(またいっぱい呑んでしまった( ˘ω˘)
Rails Boysなーwww
今年はたくさんの方にお世話になりました。
みなさんが参加してくれるので、1年を通して開催することができました。
大変だったけど、みんなと月1回会えるのを楽しみにがんばれたー( ̆ω ̆≡ ̆ω ̆)
来年もShinosaka.rbを宜しくですヾ( ̄∇ ̄=ノ
Have a nice new year ٩( ‘ω’ )و
DXRubyでプロ生ちゃんを動かしてみたヘ(^o^)ノ
これはプロ生ちゃんAdvent Calendar 2014の18日目の記事ですヘ(^o^)ノ
プロ生ちゃんの素材とDXRubyを使って、プロ生ちゃんを動かしてみます。
DXRubyとはゲーム開発初心者向けのDirectXライブラリ
注) 32bit版のRubyでのみ動作します
僕はMacなので、@wannabe53さんの"DXRuby を Wine から使う"を参考にインストールしました
DXRubyのAdvent Calendarはこっち⇒DXRuby Advent Calendar 2014
↓今回、利用したドット絵はこれ
動かしてみる
# pronama.rb require 'dxruby' require_relative 'animation' # sampleアプリから # 画像をロード image = Image.load_tiles('pronama_chan.png', 3, 4) pronama_chan = AnimeSprite.new pronama_chan.x = 0 pronama_chan.y = 0 # アニメーションの設定 pronama_chan.animation_image = image pronama_chan.add_animation :advance, 4, [1, 2] pronama_chan.start_animation :advance Window.loop do pronama_chan.update pronama_chan.draw # ESCで終了する break if Input.key_push?(K_ESCAPE) end
$ ruby pronama.rb
動いてるヘ(^o^)ノ
簡単ですねー
それでは矢印キーで上下左右に動かしてみましょう
# pronama.rb (...) pronama_chan.add_animation :retreat, 10, [10, 11] pronama_chan.add_animation :move_left, 10, [4, 5] pronama_chan.add_animation :move_right, 10, [7, 8] pronama_chan.start_animation :advance Window.loop do # 下矢印キーで前進する if Input.key_push?(K_DOWN) pronama_chan.start_animation(:advance) pronama_chan.y += 5 end # 上矢印キーで後退する if Input.key_push?(K_UP) pronama_chan.start_animation(:retreat) pronama_chan.y -= 5 end # 左矢印キーで左へ if Input.key_push?(K_LEFT) pronama_chan.start_animation(:move_left) pronama_chan.x -= 5 end # 右矢印キーで右へ if Input.key_push?(K_RIGHT) pronama_chan.start_animation(:move_right) pronama_chan.x += 5 end pronama_chan.update pronama_chan.draw # ESCで終了する break if Input.key_push?(K_ESCAPE) end
矢印キーを押すとプロ生ちゃんが動いてますヘ(^o^)ノ
どうですか?
簡単にRubyでサンプル作れちゃいましたねー
サンプルには実際のゲームなんかも同封されているので、興味のある方は是非!
Happy Hacking٩( ‘ω’ )و
サンプルコード => GitHub - pronama_game
d(゚Д゚ )☆スペシャルサンクス☆( ゚Д゚)b
Shinosaka.rb #10を開催したよーヘ(^o^)ノ #shinosakarb
今回のお題はLitaであそうぼうーです( ˘ω˘)
同じ日に第1回 Hubot×ChatOps勉強会が開催されていたので...
Hubot先生はJavaScript。
仕事でも、ProductでなければRubyでがんばりたい!(開発環境とかチャットとか
LitaはRubyってことは、そう既存のGemが使えるのだヘ(^o^)ノ
HipChatやSlackとか使おうと思ったけど、今回はIdobataを使わせていただきました。
みなさんのまとめブログがすばらしい(オレもがんばる?
いや!ここはエコシステム方式で...
適当にまとめました。 / HerokuにHubotやらLitaをデプロイしてSlack連携してみる - みなさんあのね http://t.co/wlZ7oJeIim #shinosakarb
— ひよっこ (@waday_) 2014, 11月 23
全然、適当じゃないw
勉強会のあとも触ってくれてるのうれしいヽ(´ー`)ノ
簡単ですがまとめてみました。#shinosakarb Wakayama.rbボードとLitaで温度をつぶやくchatボット(Shinosaka.rb #10にて) - YoshitoNote http://t.co/xfHzgpKnEz
— Yoshito Tanaka (@tanaka4410) 2014, 11月 24
Kobe.rbでいつもお世話になってる@tanaka4410さん♪
ボードと連携して、温度をタイマーでループさせて表示したり面白かった。
懇親会では、子供のような僕とOやんにボードについてやさしく教えてくれましたw
@meltediceさんは為替を表示するhandler作ってましたー
RubyMotionがちょっとお高いから、買い時を知らせてくれたら面白いねーって話してましたw
GitHub - lita-foreign-exchange
@honeniqさんはWikiから画像検索して表示するhandlerをつくってたよー
@kytiken_code さんはTwitterのタイムラインから画像検索して、ツイートするのを作ったみたい
なぜ、まきちゃんなのかは触れないでおきましょうw
みんな楽しんでくれたみたいヘ(^o^)ノ
chat botは全然触る機会がなかったので、僕も楽しめた。
HipChatやSlackなどと連携すると、もっと楽しくなる。
slackは独自ドメインが必要だったので、Shinosakarb.orgを取得して設定しているとこ。
メールサーバも立てる準備もしてるから、次回から使えるかもね。
Litaもたてて、みんなでどんどん拡張していくのも楽しそう。(HPだれか...w
次回は、今年最後のShinosaka.rb 12月20日(土)です。Shinosaka.rb #11
Rails4 Patternsについて盛り上がる予定です
Shinosaka.rbも今年1月から1年間続けることができました。(まだ、1回残ってるけど
今までたくさんの人が参加してくれました。
ホントに感謝です。ありがとーヘ(^o^)ノ
そして、これからも宜しくお願いします。
Happy Life Hacking With Ruby٩( ‘ω’ )و
追記
2014/11/27 slackの登録に独自ドメインは必要ないです><(あっても良いですが