Rails assets pipeline
何やらRailsを使っててJavaScriptとかをgemとかで配布してRailsプロジェクトに組み込んだりするっていうのがあったりするわけで。例えばTwitter BootstrapのCSSとかJSとかをGemfileにそういうgemを定義する事でサクッと出来るっつー訳。でその仕組み的なのがRails assets pipelineっていうのかなと、これCoffeeScriptとかならコンパイルして使えるようにする事も出来るらしいとの事(今回はやらないけど)
とりあえずこの仕組みを使ってangular.jsなプロジェクトを別にしてRailsプロジェクトに組み込むっていう事をしてみる
angular.jsなプロジェクトを作る
bundle gem sample-ui-rails
的な感じでプロジェクトを作る。やると何やらsample-ui-rails.gemspecなりが作られる訳で。でlib/sample/ui/rails.rbがあるので
require "sample/ui/rails/version"
module Sample
module Ui
module Rails
# 追加
class Engine < ::Rails::Engine
end
end
end
end
的な感じでちょいと修正しておく。でJavaScriptだとかCSSとかを提供したい場合には
- JavaScript: vendor/assets/javascripts
- CSS: vendor/assets/stylesheets
におけば良い。という事でangular.jsなコントローラーなJSを書いて上記のルールに沿った方式な所は配置する
var SampleController = function($scope, $http) {
$http.get("/sample/index")
.success(function(data) {
$scope.samples = data;
});
};
んまぁテストも書きましょうかって事でkarma initでkarma.conf.jsを作る
// Karma configuration
// Generated on Tue Oct 08 2013 05:21:20 GMT+0900 (JST)
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: "",
// frameworks to use
frameworks: ["jasmine", "ng-scenario"],
// list of files / patterns to load in the browser
files: [
"tests/angular-mocks.js", // angular.js mock library
"vendor/assets/javascripts/*.js", // source
"tests/*_spec.js" // tests
],
// list of files to exclude
exclude: [
],
// test results reporter to use
// possible values: "dots", "progress", "junit", "growl", "coverage"
reporters: ["progress"],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ["Chrome"],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
angular-mocks.jsはangular.js公式なやつに入ってるのでコピペして持ってくる。んでテスト書く
describe("SampleController", function() {
var $_httpBackend, scope, controller;
beforeEach(function() {
inject(function($controller, $rootScope, $httpBackend) {
$_httpBackend = $httpBackend;
$_httpBackend.when("GET", "/sample/index").respond([{},{}]);
scope = $rootScope.$new();
// こうしないと$_httpBackend.flushをやると、「No pending request to flush」的なエラーが出る
scope.$apply(function() {
controller = $controller("SampleController", { $scope: scope });
});
});
});
it("#construcor", function() {
expect(scope.samples).toBeUndefined();
$_httpBackend.flush();
expect(scope.samples).not.toBeUndefined();
// 上記で/sample/indexにリクエストした結果としてはArray.size == 2なのでこれはfailする
expect(scope.samples.length).toEqual(1);
});
});
karma startなりで起動してテスト実行。あとはこのプロジェクトをRailsプロジェクトで参照してコピペとかする事無く利用できるようにと
Railsプロジェクトを作る
rails new sample
で、Gemfileにangularjs-railsと上記で作ったプロジェクトの参照を追加する
gem "angularjs-rails"
gem "sample-ui-rails", :path => "/path/to/sample-ui-rails-project"
でこれだけじゃスクリプトとか参照してくれないので、app/assets/javascripts/application.jsに追加する
//= require jquery
//= require jquery_ujs
//= require_tree .
// 以降追加
//= require angular
//= require sample
あとはビューとかで
html<div ng-controller="SampleController">
<ul>
<li ng-repeat="sample in samples">
<span ng-bind-template="{% raw %}{{sample.name}}{% endraw %}"></span>
</li>
</ul>
</div>
的な事やってみて確認。書いてないけどコントローラーではrespond_toとかで(ry