Twitter Bootstrapにcompass, Sassy Buttons, zurui-sass-railsを追加する手順。

今週に入ってガリガリとHTMLとCSSを書く事がありました。
折角、Railsでシステムを開発しているという事もあるので、効率良くCSSを書く方法を調べてみました。

調査結果

  • Twitter Bootstrapの色味を変えるだけでそこそこのデザインが出来る。
  • SCSSよりSASSがイケてる。
  • SASSを使うならcompassを使うと効率的にSASSを扱える。
  • Sassy Buttonsを使えばTwitter Bootstrapぽいボタンの色違いが簡単に作成出来る。
  • zurui-sass-railsを使えばズルイデザインが出来る。

上記の事が分かったが、Twitter BootstrapはLESSで構築されていて、SASSやらcompassやらを同時にprecompile出来るのか分からなかったので、実際に実装してみました。

実際にやってみた

Railsのバージョンは3.2.9。

group :assetsに下記を追加

  gem 'less-rails'
  gem 'therubyracer', :platforms => :ruby
  gem 'twitter-bootstrap-rails'
  gem 'compass-rails'
  gem 'sassy-buttons'
  gem 'zurui-sass-rails'

gemインストール

bundle install

Twitter Bootstrapのインストール

rails g bootstrap:layout application fluid
rails g bootstrap:install

compassのインストール

bundle exec compass init --syntax sass

Sassy Buttonsのインストール

bundle exec compass install sassy-buttons


後は適当にxxx.css.sassを作成

@import compass/utilities
@import compass/css3
@import sassy-buttons
@import zurui-sass
  
.example
  +zurui-box-inner
  height: 200px
  width: 100%
  .content, .sidebar
    padding: 20px
  .content
    +box-flex(4)
  .sidebar
    +box-flex(1)
    margin-right: 1px 

.sassy-button
  +sassy-button("simple", 5px, 1.1em, #ffd71a, #ffaa1a)

viewを作成して動作が確認出来ました。

まとめ

sprocketsの機能でapplication.css記述されていればLESS、SCSS、SASSなんでもCSSにしてくれて便利。
Twitter BootstrapのSASS版もあるが、なるべく本家のアップデートに合わせたいのでLESSで良いという考えです。


[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/

自社サービスの機能を簡単にAPIで提供出来てしまう!gem doorkeeperが凄い。

自社サービスにAPIを実装する事ってあまりないですよね。
kamadoのプロダクトも現在はAPIは公開してません。

もし提供するのであれば、簡易的な方法ですが、ユーザーテーブルにtokenカラムを追加して、API用のルーティングを作成する…という方法が考えられると思います。

しかし、その実装時間でより良いAPIが実装出来るとしたら素晴らしいですよね。

そこで紹介したいのがgem doorkeeperです。
日本語の記事が見当たらなかったので記事にしました。

gem doorkeeperってどんな機能があるのか?

簡単に説明すると、
・アプリケーションの管理機能
・アプリケーションの承認管理
・スコープの設定

いってしまえば、Facebook API(に近い実装)そのまま実装出来ます。
しかもOAuth2.0を利用できます! ← 超重要

実際にやってみる

Gemfileに追加

gem 'doorkeeper', '~> 0.4.2'

コマンドの実行

bundle install
rails generate doorkeeper:install
rails generate doorkeeper:migration
rake db:migrate

これでconfig/initializers/doorkeeper.rbが作成され、DBがマイグレートされます。


次にroutesに追加

mount Doorkeeper::Engine => '/oauth'


以下がroutesに追加されます。

Routes for Doorkeeper::Engine:
          authorization GET    /authorize(.:format)                   doorkeeper/authorizations#new
          authorization POST   /authorize(.:format)                   doorkeeper/authorizations#create
          authorization DELETE /authorize(.:format)                   doorkeeper/authorizations#destroy
                  token POST   /token(.:format)                       doorkeeper/tokens#create
           applications GET    /applications(.:format)                doorkeeper/applications#index
                        POST   /applications(.:format)                doorkeeper/applications#create
        new_application GET    /applications/new(.:format)            doorkeeper/applications#new
       edit_application GET    /applications/:id/edit(.:format)       doorkeeper/applications#edit
            application GET    /applications/:id(.:format)            doorkeeper/applications#show
                        PUT    /applications/:id(.:format)            doorkeeper/applications#update
                        DELETE /applications/:id(.:format)            doorkeeper/applications#destroy
authorized_applications GET    /authorized_applications(.:format)     doorkeeper/authorized_applications#index
 authorized_application DELETE /authorized_applications/:id(.:format) doorkeeper/authorized_applications#destroy


config/initializers/doorkeeper.rbの編集。
認証システムにdeviseを使用している場合下記の様にする。

resource_owner_authenticator do |routes|
  current_user || warden.authenticate!(:scope => :user)
end


コントローラーの作成
app/controllers/api/v1/users_controller.rb

class Api::V1::UsersController < ApplicationController
  doorkeeper_for :all
  before_filter :validate_token
  before_filter :set_parameters
  skip_before_filter :verify_authenticity_token # allow CSRF

  def index
    render json: current_user
  end

  def validate_token
    return head(401) unless doorkeeper_token
  end

  def set_parameters
    sign_in 'user', User.find(doorkeeper_token.resource_owner_id)
  end

end

これで実装完了です。
画面で確認してみます。

OAuthプロバイダー側の画面遷移確認

/oauth/applicationsでアプリケーションの作成を行えます。

アプリケーションを作成




出来てますねー。

OAuthクライアント側の実行確認

実際にクライアント側から確認してみます。
下記にexampleがあるので確認に便利です。
https://github.com/applicake/doorkeeper-devise-client


こちらも出来てますね!


OAuthクライアント側(CUI)の実行確認

CUIからも確認してみます。

リダイレクトURL作成
require 'oauth2'

#clientの作成
client = OAuth2::Client.new('c5e0e923b1a257029f22dfec34056c4908f07aae67d2b00ec42d2c6e5a131637', '7f90a491763d8fe5b0419b7bc0d52c762cc2000e8d892b57f814e6aef23541c4', :site => 'http://localhost:5000')

# 認証へのリダイレクトURL作成
p client.auth_code.authorize_url(:redirect_uri => 'http://localhost:3000/users/auth/doorkeeper/callback')

#=> "http://localhost:5000/oauth/authorize?response_type=code&client_id=c5e0e923b1a257029f22dfec34056c4908f07aae67d2b00ec42d2c6e5a131637&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fusers%2Fauth%2Fdoorkeeper%2Fcallback"
トークンの取得
# トークンの取得
p client.auth_code.get_token('90cfef8de3a3c5712c6a95acd9e48f7f5355265ec462378a58c56748fd743932', :redirect_uri => 'http://localhost:3000/users/auth/doorkeeper/callback').token

#=> "38c5fcdb2d1c90d63593859c367d999049ba084817a688347e7664b24dcfed10"
API実行
p OAuth2::AccessToken.new(client, "38c5fcdb2d1c90d63593859c367d999049ba084817a688347e7664b24dcfed10").get('/api/v1/users').body

#=> {...}

承認済みアプリケーションの管理

承認済みのアプリケーションを表示するviewが用意されているのも気がきいています。

OAuthでAPIが提供出来るメリット

OAuthで通信出来るメリットって色々あると思うのですが、既に存在するgem oauth2等を利用できる事でAPIを実行するためのパッケージを簡単に実装出来るのが素晴らしいですね。

詰まったら

exampleがあります。
https://github.com/applicake/doorkeeper/wiki/Example-Applications

まとめ

ざっと試してみましたが、gem doorkeeperでこんなに簡単にAPIが実装出来るなんて素晴らしいですね。


[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/

Spree REST API の Content-typeを"application/json"に書き換えるgem、spree_api_content_type_rewriterを作成しました。

昨日の記事に引き続きSpreeネタです。

※昨日の記事。Spree REST API に実装されていない、認証系APIを追加するgem spree_api_authを作成しました。
http://d.hatena.ne.jp/camelmasa/20120821/1345529571


SpreeのREST APIはformatがjsonで出力されますが、Content-typeが"text/html"になってしまっていて、application/jsonを期待するネットワーク系ライブラリでエラーと判断されます。(BODYは正しいjsonだとしても)

なのでそれを書き換える実装をmiddlewareで行っていたのをgem化しました。
https://github.com/camelmasa/spree_api_content_type_rewriter



…しかし、明らかにバグだよなと作ってから思い、issueで質問した所、やはりバグですぐさまbug fixされました。
https://github.com/spree/spree/issues/1866

結果的に良かったのですが、gem化する必要なかったなと後悔。
明らかなbugに関してはissueで確認後実装を行う様にしたいと思います。

メモ

勉強になった部分メモ。
spreeのextensionはgemで提供されるのですが、gem内でconfig.middleware.useを使うときは注意が必要です。

extension内でconfig.middleware.useをしても実行されません。
下記の様にするとmiddlewareを実行する事ができました。

Spree::Core::Engine.middleware.use "SpreeApiContentTypeRewriter::Middleware::ContentTypeRewriter"

ただ、Gemfileに追加するだけで、挙動を変化させるのは混乱の元になると思うので、config.middleware.useするのはアプリケーション側のconfig/application.rbで指定する形の方が良いと思われます。


[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/

Spree REST API に実装されていない、認証系APIを追加するgem spree_api_authを作成しました。

SpreeはRailsで作成されたECパッケージです。PHPでいうところのECCubeでしょうか。
gemで提供されています。
http://spreecommerce.com/

最近触り始めているのですが、Spreeは各種機能をREST APIという形で提供しています。
しかし、このREST APIにはユーザー登録、ユーザーログインの機能は実装されていません。
(gem spree-apiを使用すると出来なくないのですが、既存のREST APIの挙動を変えてしまいます)

ユーザー登録、ユーザー認証だけが出来ればとりあえずAPIは事足りるので、認証系APIを追加するgemを作成しました。
https://github.com/camelmasa/spree_api_auth

Gemfileに追加してbundle installでAPIが追加されます。

追記

spreeの仕様だと、REST APIを仕様出来るユーザーを管理画面から選択する必要があるのですが、このgemを使うと、ユーザー登録が成功したタイミングでその許可を行います。


[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/

Rails + capistranoの環境で、assetsに変更が無い場合assets precompileを飛ばして、デプロイを高速化する方法。

前に設定云々でハマった事があったのでメモ。


高速化のソースコードについては下記。
http://stackoverflow.com/questions/9016002/speed-up-assetsprecompile-with-rails-3-1-3-2-capistrano-deployment


config/deproy.rb内に下記を追加

namespace :deploy do
  namespace :assets do
    task :precompile, :roles => :web, :except => { :no_release => true } do
      from = source.next_revision(current_revision)
      if capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ lib/assets/ | wc -l").to_i > 0
        run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
      else
        logger.info "Skipping asset pre-compilation because there were no asset changes"
      end
    end
  end
end


…とまでは書いてあるのですが、1つ条件があって、:deploy_via が :remote_cacheになってる時だけ上記の高速化が有効になります。

set :deploy_via, :remote_cache としている場合、各リビジョンのディレクトリ内に.gitを作成し、ローカルにgitレポジトリを作成し高速化を行います。
http://torokeru.tv/mameblog/?p=195



:remote_cache以外(:export等)を指定していると、上記ソースコード

if capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ lib/assets/ | wc -l").to_i > 0

部分で、wc -lが必ず0となりprecompileしてくれません。要注意。


なんで、:remote_cache以外使うんだって話なのですけどね…。


[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/

rubyで大学、大学院、短大、専門学校、高専全ての学校名と学部を取得する方法。

色々調べ物をしていて、副産物が出来たので公開。
変数名とか適当です。

# encoding: UTF-8
require "json"
require 'open-uri'
require "net/http"

module Net
  class HTTPRequest
    self.class_eval{
      attr_reader :postdata
      def initialize(path, initheader = nil)
        klass = initheader["postdata"] ? HTTP::Post : HTTP::Get if initheader
        @postdata = initheader.delete("postdata")
        super klass::METHOD,
          klass::REQUEST_HAS_BODY,
          klass::RESPONSE_HAS_BODY,
          path, initheader
      end
    }
  end
  class HTTP
    self.class_eval{
      alias :_request :request
      def request(req, body = nil, &block)
        body = req.postdata if req.respond_to?(:postdata)
        _request(req, body, &block)
      end
    }
  end
end

[0,1,2,3,4,5].each do |s|
  ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''].each do |h|
    JSON.parse(open('https://job.rikunabi.com/2014/accounts/regist/ajax/school/gakko/', {"postdata" => "dGakushuCode=#{s}&dGakkoHead=#{h}"}).read).each do |school_name|
      next if school_name['value'] == '' || school_name['value'] == 'XXXX'
      JSON.parse(open('https://job.rikunabi.com/2014/accounts/regist/ajax/school/gakubuGakka/', {"postdata" => "dGakkoCd=#{school_name['value']}"}).read).each do |school_gakubu|
        next if school_gakubu['value'] == '' || school_gakubu['value'] == 'XXXX'
        p "#{school_name['label']} #{school_gakubu['label']}"
      end
    end
  end
end

[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/

XCodeで複数ファイルに "-fno-objc-arc" フラグを付ける方法。

下記の記事そのままなのですが、どこからこの画面に遷移出来るか分からなかったので調べました。
http://iphone-dev.g.hatena.ne.jp/laiso/20111115/1321339367


How do you use Compile Sources in Xcode 4.0?
http://stackoverflow.com/questions/5762916/how-do-you-use-compile-sources-in-xcode-4-0


無事コンパイル完了。


[PR]Spreeの情報を集めています。

ECを持ちたい方、仕事でECを使いたい方向けのコミュニティサイトです。
このサイトでは世界で最も使用されているECの1つであるSpreeについての情報を提供しています。
http://spreecommerce.jp/