Railsのenumをmodel横断的に使おうとしたときのメモ
複数のモデルにステータスなどの共通した値と処理を持たせたい!と思ってRails4.1のenumを使いつつ、concernなmoduleに切り出そうと思ったら、enumはActiveRecord所属だったので、困ってしまったときのメモ。
しょうがないので、ActiveRecordを継承したクラスを作ってそこに処理をまとめようとした。
class StatusRecord < ActiveRecord::Base before_create :set_status enum status: {draft: 0, published: 1} private def set_site self.status = some_helper_method end end class Article < StatusRecord ~snip~ end
そしたら、statusってテーブルがねーよッ、というニュアンスにエラーがでた。
ActiveRecord::StatementInvalid:
Mysql2::Error: Table 'hoge.status' doesn't exist: SHOW FULL FIELDS FROM `status `
調べてみると、
self.abstract_class = true
として、紐づくテーブルがないことを宣言する必要があった。
class StatusRecord < ActiveRecord::Base self.abstract_class = true before_create :set_status enum status: {draft: 0, published: 1} private def set_site self.status = :draft end end
これでOK牧場。
Railsで送信するメールのSubjectに一括で定型文を入れたいときのメモ
Webサービスから配信されるメールって最初にサービス名が入っているじゃないですか。
[HogeFuga] 会員登録のお知らせ
みたいに。
で、そのタイトルを毎回指定するのを忘れた、とか、忘れたわけじゃなくて、イチイチ入れるのってバカじゃないの?とかそういうケースの話。
ActionMailerのinterceptorを使う。
http://api.rubyonrails.org/classes/ActionMailer/Base.html#label-Observing+and+Intercepting+Mails
config/initializers/mail_subject.rb
class EmailSubject def self.delivering_email(mail) mail.subject = "[HogeFuga]" + mail.subject end end ActionMailer::Base.register_interceptor(EmailSubject)
これで、全部のメールタイトルの先頭に[HogeFuga]が挿入されるよ!
やったね!たえちゃん!
- 出版社/メーカー: ソニー・コンピュータエンタテインメント
- 発売日: 2014/09/11
- メディア: Video Game
- この商品を含むブログ (3件) を見る
Coffeescriptでページを離れる前に警告を表示する方法
入力フォームとかで、うっかりバックスペースとか押しちゃって入力内容パー、みたいな事態を防ぎたいケースの話し。
beforeunloadというイベントを使う。
$(window).on('beforeunload', (evt)-> return 'hogehoge' )
これでリンク踏んで画面遷移するときはもちろん、リロードもブラウザを閉じたときも発火してアラートがでる。
一部のリンク押下では出したくない場合は以下のようにやればかなり対応できる。
@$('.js-no-beforeunload').on('click', -> $(window).off('beforeunload') ) $(window).on('beforeunload', -> return 'hogehoge' )
こんな感じで、クリックイベントを取ってbeforeunloadイベントを外す。
リロードを完全に制御するのはブラウザ付属のリロードボタンクリックを判別しなければいけないので、無理かもしれない。どっかの誰かがクリックの座標で判断するってやってたのを見たけど、やる気がおきなかった。
rspecのcontrollerのテストでログインチェックのテストを共通化したメモ
ログインがあるアプリだと、各コントローラでログインしている場合はこう!ログインしてない場合はこう!というテストが書きたくなる。
具体的なテストコードはこんな感じでござる。
describe FoosController do let(:user) { FactoryGirl.create(:user) } describe 'GET #new' do describe 'GET #new' do context 'by anonymous user' do before do get :new end it { is_expected.to redirect_to signin_path } end context 'by login user' do before do sign_in user get :new end it { is_expected.to render_template('new') } end end end
これがいろんなところにできていたので、まとめたくなった。
要はgetとかのaction部分と、結果のテンプレートの種類あたりが可変にできればよいのだ。
こんなときの解決法の1つとしてshared exampleがある。
describe FoosController do let(:user) { FactoryGirl.create(:user) } describe 'GET #new' do it_should_behave_like 'authentication required' do let(:action){ get :new } let(:template) {'new'} end end end
support/authentication_required.rb
require 'spec_helper' shared_examples 'authentication required' do context 'by anonymous user' do before do action end it { is_expected.to redirect_to signin_path } end context 'by login user' do before do sign_in user action end it { is_expected.to render_template(template) } end end
Rails4のconcernsなmoduleのテストをrspecで書く方法で書いたけど、shared_examplesをsupportの下に配置しているのは、ここだとspec実行時にロードされるから。
これでけっこうDRYになったね。
- 出版社/メーカー: アサヒビール
- メディア: 食品&飲料
- クリック: 17回
- この商品を含むブログ (4件) を見る
paperclipをAWSのS3+Cloudfrontで使うときの設定メモ
ワリと時間かかったのでメモ。
config/environments/production.rb
config.paperclip_defaults = { storage: :s3, s3_host_alias: 'your.cloudfront.net', path: '/:class/:attachment/:id/:style/:hash.:extension', url: ':s3_alias_url', s3_host_name: 's3-ap-northeast-1.amazonaws.com', s3_protocol: '', s3_credentials: { bucket: 'your_backet_name' } }
config/initializers/paperclip.rb
Paperclip::Attachment.default_options[:hash_secret] = 'abutorudamuraruomunisunomunisuberuesuhorimaku' Paperclip::Attachment.default_options[:default_url] = 'no_:style.png'
ポインツ
- initializersには共通の設定を書くが(書かなくてもいいけど)、envrionmentsで上書きする前提で書くと、場合によってはハマるからあまりおすすめしない
- s3_host_nameは東京リージョンのときは必須
- http,httpsを状況によって出し分けるには、s3_protocolに空文字を渡しておく
- クレデンシャル関係はこのケースではEC2自体に権限設定してあるが、色んなやり方があるので好きようにする。
- 作者: すがわらまさのり,前島真一,近藤宇智朗,橋立友宏
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/06
- メディア: 大型本
- この商品を含むブログ (8件) を見る
今使っている+今度使ってみたいGemリスト 2014年 夏 ver.
使っているやつ
使っているやつはGemfileを晒す。なお、複数プロジェクトのGemfileをマージしたものなので、全部同時に使ってるわけじゃない。
gem 'rails', '~> 4.1.4' gem "mysql2", "~> 0.3.16" gem 'bootstrap-sass', '~> 3.1.1.0' gem "sass-rails", github: 'rails/sass-rails' gem 'normalize-rails', '~> 3.0' # reset css gem 'bourbon', '~> 3.2.3' gem 'neat', '~> 1.6.0' gem 'bitters', '~> 0.10.0' gem 'therubyracer', '~> 0.12.1' gem 'uglifier', '~> 2.5.3' gem "coffee-rails", "~> 4.0.1" gem "jquery-rails", "~> 3.1.1" gem 'jbuilder', '~> 2.1.3' gem 'i18n-js', '~> 3.0.0.rc6' gem 'backbone-on-rails', '~> 1.1.1.0' gem 'jquery-ui-rails', '~> 5.0.0' gem 'jquery-modal-rails', '~> 0.0.4' gem 'omniauth', '~> 1.2.2' gem "omniauth-twitter", "~> 1.0.1" gem "omniauth-facebook", "~> 1.6.0" gem 'faker', '~> 1.4.2' gem 'tokens', '~> 2.1.1' gem "settingslogic", "~> 2.0.9" gem "bcrypt-ruby", "~> 3.1.5" gem 'kaminari', '~> 0.16.1' gem 'paperclip', '~> 4.2.0' # https://bugs.ruby-lang.org/issues/859, http://stackoverflow.com/questions/22660147 gem 'open_uri_redirections', '~> 0.1.4' gem 'active_decorator', '~> 0.3.4' gem 'counter_culture', '~> 0.1.24' gem 'countries', '~> 0.9.3' gem 'country_select', '~> 1.3.1' gem 'activerecord-import', '~> 0.5.0' gem 'mail_form', '~> 1.5.0' gem 'cells', '~> 3.11.1' gem 'impressionist', '~> 1.5.1' gem 'public_activity', '~> 1.4.1' gem 'retina_rails', '~> 2.0.1' gem 'remotipart', '~> 1.2.1' gem 'unicorn', '~> 4.8.3' gem 'rails_autolink', '~> 1.1.6' gem 'newrelic_rpm', '~> 3.9.0.229' gem 'whenever', '~> 0.9.2', require: false gem 'aws-sdk', '~> 1.48.1' gem "awesome_nested_set", "~> 3.0.0.rc.2" gem 'paranoia', '~> 2.0' gem 'mini_magick', '~> 3.7.0' gem "ngram", "~> 1.0.0" gem "moji", "~> 1.6" gem "unread", "~> 0.3.1" gem "ransack", github: "activerecord-hackery/ransack", branch: "rails-4" group :development do gem "letter_opener", "~> 1.2.0" gem 'quiet_assets', '~> 1.0.3' gem 'capistrano', '~> 3.2.1' gem 'capistrano-rails', '~> 1.1.1' gem 'capistrano-rbenv', '~> 2.0.2' gem 'capistrano-bundler', '~> 1.1.2' gem 'capistrano3-unicorn', '~> 0.1.1' # 0.2.1にすると、deploy後、リロードのたびに新旧のページが入り乱れる(プロセスの再起動が上手く行っていない?) gem 'better_errors', '~> 1.1.0' gem 'rubocop', '~> 0.24.1', require: false end group :development, :test do gem 'rspec-rails', '~> 3.0.2' gem 'rspec-mocks', '~> 3.0.3' gem 'spring', '~> 1.1.3' gem 'spring-commands-rspec', '~> 1.0.2' end group :test do gem 'capybara', '~> 2.4.1' gem 'poltergeist', '~> 1.5.1' gem 'factory_girl_rails', '~> 4.4.1' gem "shoulda-matchers", "2.6.1", require: false # 2.6.2に上げるとテストが通らなくなる。原因は追ってない。 gem "database_cleaner", "~> 1.3.0" gem 'rake_shared_context', '~> 0.2.1' gem 'timecop', '~> 0.7.1' end group :doc do gem 'sdoc', require: false end
使ってみたいやつ
- https://github.com/flyerhzm/bullet
- N + 1問題抽出
- https://github.com/railsbp/rails_best_practices
- コードの品質チェック
- https://github.com/activerecord-hackery/squeel
- ActiveRecordで条件指定が見やすく書けるようになる
- https://github.com/gregbell/active_admin
- 管理画面自動生成
- http://www.thinreports.org
- 帳票作成
- https://github.com/mbleigh/acts-as-taggable-on
人気があるようだけど、使ってみてやめたやつ
- https://github.com/plataformatec/devise
- デフォルトで全部間に合わすならいいけど、そうでない場合は実装の詳細を把握してる時間で、実装できちゃう機能がほとんど。少しいじるたびに実装調べる時間がもったいない。
- https://github.com/ctran/annotate_models
- そのうち再実行する忘れて実態からかけ離れることが多く、自動化するレベルのこととも思えない。加えてファイルのスペース取られるのがイヤ。テーブル構成なんか最初だけで、しばらくやってればだいたい頭に入るのでmigration見るので充分かな。
選択の基準
何かのイケてそうなGemを見つけたら、https://www.ruby-toolbox.comで
- 競合がないか
- 活動は活発か
- 使っている人は多いか
などを確認してから採用に踏み切る
migrationが絡むやつはより慎重に・・・。
- 作者: すがわらまさのり,前島真一,近藤宇智朗,橋立友宏
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/06
- メディア: 大型本
- この商品を含むブログ (8件) を見る
Androidアプリ開発の手引 2014年 君がいた夏ver.
最後にAndroidアプリをいじっていたのはもう2年近く前のことだ。
2年も経てばスタンダードも大きく変わっているだろうと再度初心に返り、イチからプロジェクトを作ってみたいと思うこの夏。
開発マシン
OSX10.9.4
参考
http://developer.android.com/index.html
まずは公式ですよ、奥さん!質が高いドキュメントがそろってますから!
ここを読んでない輩は、こんなクズブログ読んでないで、ひとそろい公式読んでからまた来なさい。
まぁ、そのときは来ても意味なくなってると思うけどな!
JAVA
そもそもJAVAの最新バージョンってなんだっけ、と思ってJAVAのサイトいったら「あなたとJAVA」とか出てきてこのコピー必要だったの?ってモヤッた。
がともかく、2014年8月時点ではJDK8が最新だった。
で、Androidの対応バージョンはどうなんだ。2年前は6だったけど、7くらいは使えるようになってんじゃねーの?と思ったら未だに6だった。
http://developer.android.com/sdk/index.html
あれー、7に対応したってのをどっかで見かけたような気がしたんだけどなぁ。別にstringのswitchくらいしか使いそうな機能はないんだけど。
と思ったら一部を除いて使えるみたい。
http://qiita.com/hidekuro/items/6a252c82132ed5d279a4
stackoverflowなど、観測範囲では特に7によるトラブルは見当たらなかったけれども、公式は6推しのようなので、受託とかなら6を使っておいたほうがいいかもね。
まあ、今回は7でいくけど。
ここからdmgゲット。
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
$ java -version
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
IDE
何を使うかだけど、今はAndroidStudioってのがあるらしいね!しかもIntelliJのところが作ってんだね!公式もやや推し気味だね!
で、そんなものがないときから、IntelliJでやってたぼくは当然IntelliJ+Androidプラグインを使う。
貧乏な人はAndroid Studioを使えばいいんじゃないでしょうか。
ってか、違いってあるんかね。
http://blog.jetbrains.com/idea/2013/05/intellij-idea-and-android-studio-faq/
Is Android Studio a fork of IntelliJ IDEA?
No. Android Studio and the Android plugin for IntelliJ IDEA are built from the same code, and all of the changes in Android Studio are, and will continue to be, available in IntelliJ IDEA releases.
ということで、Android StudioもAndroidプラグインも同じなんで、AndroidStudio使ったからって損することはないらしい。
ただ、さっきのリンクの他のFAQでAndroid依存でないところの基本的な機能はIntelliJにしか乗らないものはあるのでIntelliJを使っている人はIntellijを使ったほうがいいって言ってた。
なお、プロジェクトは同じ形式なので、どっちからどっちに乗り換えても問題ないらしい。
Android SDK
このケースだと、スタンドアロンで入れることになるんだと思う。
http://developer.android.com/sdk/installing/index.html?pkg=tools
この通りにすればいいと思う。
Zipダウンロードして、回答して、~/Developmentあたりに置いとけばいいんじゃないでしょうか。
その後、パスを通してコンソールでandroidって打つと、SDKマネージャが立ち上がるのでバリバリインストールしたいバージョンのライブラリを入れておくべし。
$ export PATH=$PATH:~/Development/android/sdk/platform-tools:~/Development/android/sdk/tools
$ android
こんな感じでいいと思う。
というのも、ぼくは、既に入っていて記憶に無いけど4.4.2まで入っているのでこのプロセスは実施してないのでちょっと違うところがあるかも。
※追記)今はhomebrewで入れられるらしい
プロジェクト作成
とりあえずIntelliJで新しいプロジェクトを作る
Create New Project > Android > Application Module
で、アプリ名とかパッケージ名とかいれるところは今回はとりあえずそのままで行く。ついでにHello world activityも作ってもらおう。
で、SDK指定するところがあるので、さっき入れたSDKのディレクトリを指定すると、APIレベルの候補を出してくるので好きなのを選ぶ。今回は現時点で最新のAPI19を選んでおいた。
で、完了すると、何もでない。が、これは時間がかかっているだけなので、待つべし。
ロードが完了したら設定をいじる。
ProjectSettings(コマンド+;)で、
エミュレータ
2年前は死ぬほどおっそいエミュレータしか提供しておらず、やっとこさ爆速エミュレータが不安定ながらも登場したてのほやほやでしたが、今はどうなんでしょうか。
で、調べてみるとGENYMOTION という名前をよく見かけたので試してみることにした。
http://www.genymotion.com/
https://shop.genymotion.com/index.php?controller=order-opc
Freeプランでも問題ないと思う。Pixel Perfectだけ若干気になるけど、このへんは実機で確認すればいいべ。
もろもろ手続きしてダウンロードする。あっ。IntelliJ IDEA Pluginもある!
あと、VirtualBoxが必須なのでこいつもダウンロードしておく。
https://www.virtualbox.org/wiki/Downloads
で、これらをインストールしてGENYMOTIONを起動してみる。
すると、GalaxyS4のイメージをインストールするか聞かれたので、それを選んだらなぜかエラーになった。調べる気がおきなかったので、あとからGoogle Nexusのイメージを追加した。
追加している間、Genymotionがステキさをアピールしてくる。
Genymotion is fast! CPU and GPU hardware accelerated. Boot more than 3 times faster, deploy your app 2 times faster!
イメージカラーが赤いのでやっぱり3倍速いらしい。
インストール後、エミュレータを起動してみる。うん、なかなか速い。
Hello World
で、プロジェクト作成時にHello World activityを自動生成するようにしたので、とりあえずアプリとしては成立している状態のはず。
起動してみる。
Run > run 'myapp'
すると、さっき追加したエミュレータがdeploy先の選択肢に出てきたので選択したら・・・
できた!
なお、さっきHello World activityを生成するときに、APIレベルを19に設定しているので、エミュレータもAPI19をサポートしているやつじゃないと動かない。それ以外のエミュレータを入れてしまった場合は、AndroidManifestのandroid:minSdkVersionをいじればOK。
次は、テストとかその辺かな・・・。
- 作者: 木田学,おかじゅん,渡辺考裕,奈良進,荒川祐一郎,兒島友三郎,石立宏志,小林正興,テックファーム
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る