Ruby」カテゴリーアーカイブ

Rails 3.2.12から4.2.0にアップデートした

ども。
やましもです。
今日は天神で買い物しつつ、びくドンで朝からハンバーグ食べたりしてました。
休憩がてらスタバ入って退屈だったのでRailsUpdate業に勤しんでいます。

手順

  • Gemfile
gem 'rails', '~> 4.2.0'

と追記して、
bundle update
で奇跡的に何もなくバージョンアップされることを期待しました。

カジュアルにrails sを実行。

~/teams (master) <S><U>% rails s                                                                                                                                                             [14:58:45]
=> Booting WEBrick
=> Rails 4.2.0 application starting in development on http://localhost:3000
=&gt; Run <code>rails server -h</code> for more startup options
=&gt; Ctrl-C to shutdown server
config.eager_load is set to nil. Please update your config/environments/*.rb files accordingly:

<ul>
<li>development - set it to false</li>
<li>test - set it to false (unless you use a tool that preloads your test environment)</li>
<li>production - set it to true</li>
</ul>

<dl>
<dt>Exiting</dt>
<dt>/Users/yamashitakazuhiko/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/activerecord-4.2.0/lib/active_record/dynamic_matchers.rb:26:in `method_missing&#039;/Users/yamashitakazuhiko/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/orm_adapter-0.5.0/lib/orm_adapter/adapters/active_record.rb:81: warning: already initialized constant ActiveRecord::Base::OrmAdapter</dt>
<dt>/Users/yamashitakazuhiko/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/orm_adapter-0.5.0/lib/orm_adapter/adapters/active_record.rb:81: warning: previous definition of OrmAdapter was here</dt>
<dd>undefined method `whitelist_attributes=&#039; for #&lt;Class:0x007fc3f88f07f0&gt; (NoMethodError)

まあ、この時点でいらんことやらなければよかったなんて思うわけですが、
ネットに情報あったので対応していきます。

まずは不足してるgemを追加。

  • Gemfile
 gem &#039;protected_attributes&#039;
 gem &#039;rails-observers&#039;
 gem &#039;actionpack-page_caching&#039;
 gem &#039;actionpack-action_caching&#039;
 gem &#039;activerecord-deprecated_finders&#039;

次に、Rails4系から自動Explainがなくなったらしいので、パラメーターを削除。
* /config/environments/development.rb

config.active_record.auto_explain_threshold_in_seconds = 0.5

ここまでやってやっと、、画面が・・・・

でない♥

\"スクリーンショット


undefined method `set_table_name\' for TeamInformation(Table doesn\'t exist):Class

どうもパラメーター変わったみたいですね。
まるっと置換して・・・

 find ./models -iregex &quot;.*rb&quot; | xargs sed -i &#039;&#039; &#039;s/set_table_name/self.table_name =/g&#039; 

でけたーーー!!!

\"スクリーンショット

というところで、僕はジムに行って、昨日より強くなってきます。

カテゴリー: Ruby

色々スクレイピングしてGoogleスプレッドシートにぶっこむ

弐ノ弐ハッピーアワー行ってきました。
どうも、山下です。
知ってますか?弐ノ弐のハッピーアワー。
毎日17時〜18時半まで生ビールと焼き餃子が半額なんです。
暴飲暴食な僕と宮路くんでいっても二人で4800円ですよ!!!
福岡の皆さん是非弐ノ弐ハッピーアワーお勧めです。
(普通に美味しいです)

さて、今日は昼間ちょっと時間があったので、rubyでスクリプト書いてました。

解決したいこと

今ぼくはGMOペパボという会社でWEBエンジニアとして働いていて、コードは全てGitHubで管理されています。
僕達が書いたコードの本番リリースは決済システムでリリース決済が下りた後、デプロイツールで数クリックで本番にデプロイされる状況にあります。

ただ最近ちょっと悩みなのが、バグが原因でシステム停止などが起こった場合に、その時の温度感だけで

「最近不具合多くね?停止時間長くね?あいつ不具合多くね?」

なんて話になりがちであったりします。

しかし、デプロイツール非常に便利なのですが、不具合があった時にリリース回数、システム停止時間、影響顧客数などの統計を取ろうと思った時になかなか難しかったりして、数字での管理が難しい状況に有ります。
最初に考えたのはRedmineあたりで連携させてうまいことやれないかな、、、なんて検討してみたのだけど、ちょっと都合よさげなプラグインは見つけきれませんでした。

こうなると自前でAPI叩いてDBにデータぶっこんで、上モノをRailsあたりで書こうかなんて話になりがちですが、ちょっとした数字を管理したいのに稼働かけまくるのもイマイチなので、データの出力先としてGoogleスプレッドシートいんじゃね??なんて思ったわけです。

こちらGoogleからAPIも提供されていて、WEB上のスプレッドシートのセルにデータを書き込むなんてこともAPIで出来ますし、各言語のラッパーライブラリもあって結構簡単に使える感じでした。
なにより普通にExcelと機能変わらないので数字こねくり回すの非常に便利なんですね。
僕、Excelマイスターですし

書いてみた

実際仕事で使うかどうかは別にして、ペパボだとリリースは社内システムの決済が下りた後でないと実行できない運用ルールがあるので、その決済システムからデータを抜くイメージでスクレイピングスクリプトを書いてみました。
今日は社内にアクセスする環境がなかったので便宜上Amazonにログインして購入履歴をスプレッドシートに吐いてみたのです。
コードはGitHubにございます。

スクレイピングの方はシステムに合わせて書く必要がありますが、Googleスプレッドシートはこんな感じですね。

        # ログイン
        def login(id=nil,password=nil)
            id ||= @@id
            password ||= @@password
            sid ||= @@sid
            @g = GoogleDrive.login(id, password)
            @s  = @g.spreadsheet_by_key(sid).worksheets[0]
        end

        # データ追加
        def addData(lst)
            rn = 1
            cn = 1
            lst.each{|row|
              row.each{|col|
                @s[rn,cn] = col.to_s
                cn += 1
              }
              cn = 1
              rn += 1
            }
            @s.save
        end

ログインして、addDataに多次元配列渡してあげると行1列1から順に書き出してくれる感じです。
ただし一個だけ注意事項。

~/dev_mechanize (master) % ruby client.rb
WARNING: GoogleDrive.login is deprecated and will be removed in the next version. Use GoogleDrive.login_with_oauth instead.

Google Driveの認証方式が現状はGoogleアカウントID、パスワードで通りますが、次のバージョンからはトークンを利用したoauthじゃないと通らなそうなので、そこは対応が必要です。

出力されたイメージはこんな感じですね。
\"スクリーンショット
TENGAとか買ってなくてよかった
どこの会社も業務系のシステムからデータ抜きたいけどAPIとかねえしな・・・なんていう話はよくあると思うので、活用して見てはどうでしょうか。。
それでは!

カテゴリー: Ruby

Rubyでストラテジー

送別会SONY ILCE-7 (35mm, f/4.5, 1/80 sec, ISO1600)

どもー。
やましもです。
今週からGMOペパボの福岡支社で働き始めました。
まだまだペパボのサービスに一切タッチしていないので
何がどうこうってわけじゃないんですが、
新しい環境で毎日刺激を受けて楽しく、
企業としての風土が素晴らしいな、なんて思う毎日です。
あと2週間位はトレーニングで養殖な環境なのでその間に
なるべく色々吸収します。

さて、今日は天神でぶらぶらしつつ、スタバでお茶してて暇だったので
rubyでストラテジーパターンを書いてみました。
なんでかわからないんですけど、いつも「ストテラジー」って言っちゃうんですよね。
なんなんでしょうねこれ。

ストラテジーパターンはアルゴリズムをまるっとクラス化して、
インターフェースは抽象クラスそのままに、
具象クラスを切り替えて使うようなパターンですね。
後々アルゴリズムが変わるようなときや、複数のフォーマットでの
ファイル出力が想定されるときなどに使えるパターンです。
ファクトリーとすごく親和性があるクラスだななんて思っています。

今回は2ファイルに分割してます。
GitHub デザインパターン

Converter.rb
[Ruby]
#インターフェースとなる抽象クラス
class AbsConverter
def output_line(arr)
raise “this method is abstract class method!!”
end
end

#具象クラス カンマ出力
class Comma_Converter < AbsConverter def output_line(arr) puts arr.join(',') end end #具象クラス タブ出力 class Tab_Converter < AbsConverter def output_line(arr) puts arr.join("\t") end end #切り替えクラス class Context def initialize(converter) @converter = converter end def set_converter(converter) @converter = converter end def output_line(arr) @converter.output_line(arr) end end [/Ruby] AbsConverterがインターフェース相当の抽象クラス。 こやつを継承する形で、配列をカンマ区切りで出力するクラス、タブ区切りで出力するクラスを 定義しています。 Contextクラスは実際にConverterを振り分けるクラスで、コンストラクタでセットするか、 set_converterメソッドで自身のインスタンス変数にコンバーターをセットします。 Strategy.rb
[Ruby]
require ‘./Converter.rb’

arr = [‘ruby’,’rails’,’perl’,’psgi’]
converter = Context.new(Comma_Converter.new())

puts ‘1.カンマコンバーターの出力’
converter.output_line(arr)

puts “\n”

converter.set_converter(Tab_Converter.new())
puts ‘2.タブコンバーターの出力’
converter.output_line(arr)
[/Ruby]

実際の使用例がこちら。
arrという配列に[‘ruby’,’rails’,’perl’,’psgi’]を格納し、
それを各コンバーターから出力しています。

実行結果
[Shell]
~/learn_perl/DesignPettern/Strategy (master) % ruby Strategy.rb [15:05:13]
1.カンマコンバーターの出力
ruby,rails,perl,psgi

2.タブコンバーターの出力
ruby rails perl psgi
[/Shell]

あー、もう15時。
皆さん良い週末を。

カテゴリー: Ruby

define_methodでハマった。

夏休みも残すところ一週間弱。
最近はTeamsの開発の手をちょっと止めて、Rubyの言語仕様を勉強したり、
友達に頼まれてChrome拡張作らされたりといった日々を過ごしています。
Rubyはクックブックを主に読み込んでいます。
その中のレシピ4.10でハマりました。
[Ruby]
class Numeric
[[“add”,”+”],[“subtract”,”-“],[“multiply”,”*”],[“divide”,”/”]].each do |method,operator|
define_method(“#{method}_2”) do
method(operator).call(2)
end
end
end

puts 4.add_2
[/Ruby]
なんてことないadd_2〜divide_2というメソッドを定義するだけのレシピ、しかし、
methodの中にadd〜divideが順次読み込まれるので、
定義されたメソッドの中にadd(operator).call(2)のように
再帰的に読まれるように一見思えてしまいます。

結論から言うとeachの引数でもらうmethod
[Ruby]
[[“add”,”+”],[“subtract”,”-“],[“multiply”,”*”],[“divide”,”/”]].each do |method,operator|
[/Ruby]
define_methodで定義するメソッドの中身のブロックに書かれるmethodが重複していて紛らわしく、
[Ruby]
method(operator).call(2)
[/Ruby]
ハマっちゃいました。
前者は単なるeachのローカル変数、後者はmethodというメソッドなのですね。
addの場合はmethod(+).call(2)のような挙動となり、
単純に2を足して返すだけの関数となるわけです。
ここもうちょっと変数名変えて書いてほしいななんて思った今日このごろ。

カテゴリー: Ruby

自分メモ Rails周りでよく使うコマンドとか

ルーティングの確認
[Shell]
[root@www38181u teams]# rake routes
(in /var/www/Teams)
new_user_session GET /users/sign_in(.:format) users/sessions#new
user_session POST /users/sign_in(.:format) users/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) users/sessions#destroy
user_password POST /users/password(.:format) users/passwords#create
new_user_password GET /users/password/new(.:format) users/passwords#new
edit_user_password GET /users/password/edit(.:format) users/passwords#edit
PUT /users/password(.:format) users/passwords#update
cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel
user_registration POST /users(.:format) users/registrations#create
new_user_registration GET /users/sign_up(.:format) users/registrations#new
edit_user_registration GET /users/edit(.:format) users/registrations#edit
PUT /users(.:format) users/registrations#update
DELETE /users(.:format) users/registrations#destroy
team_main POST /team/main(.:format) team/mains#create
new_team_main GET /team/main/new(.:format) team/mains#new
edit_team_main GET /team/main/edit(.:format) team/mains#edit
GET /team/main(.:format) team/mains#show
PUT /team/main(.:format) team/mains#update
DELETE /team/main(.:format) team/mains#destroy
[/Shell]

名前空間つきのコントローラーの作成

[Shell]
[root@www38181u teams]# rails g controller Team::main
create app/controllers/team/main_controller.rb
invoke erb
create app/views/team/main
invoke test_unit
create test/functional/team/main_controller_test.rb
invoke helper
create app/helpers/team/main_helper.rb
invoke test_unit
create test/unit/helpers/team/main_helper_test.rb
invoke assets
invoke coffee
create app/assets/javascripts/team/main.js.coffee
invoke scss
create app/assets/stylesheets/team/main.css.scss
[/Shell]

名前空間つきコントローラーのルーティング設定
[Shell]
namespace ‘team’ do
resources :main
end
[/Shell]

DeviseAPI周り

  • ログイン確認
  • before_filter :authenticate_user!
    

    部分テンプレートにインスタンス変数を渡す

    	<%= render partial: "japan_select", locals: {city: @city}%>
    
カテゴリー: Ruby