HAMLである条件がtrueの時だけあるclassをタグに追加したい場合
.post{:class => ("gray" unless post.published?)}
HAMLである条件がtrueの時だけあるclassをタグに追加したい場合
.post{:class => ("gray" unless post.published?)}
ActionView/Helpers/AssetTagHelper、asset(画像、CSSなど)ホストのチューニングについての勉強メモです。
Gistのmarkdownはembedする時にうまくスタイルをレンダリングしてくれないようです。。。
orz….https://gist.github.com/1350279で見たほうがいいかも知れません。
## asset hostを指定image_tag("rails.png")のhelper methodで生成するリンクはデフォルトでは同じホストのpublicフォルダを指しています。それを変更したい場合は`config/environments/production.rb`の`ActionController::Base.asset_host`をいじります。
```rubyActionController::Base.asset_host = "assets.example.com"```
```erbimage_tag("rails.png")# => <img alt="Rails" src="http://assets.example.com/images/rails.png?1230601161" />```
## asset hostを複数指定ブラウザが一度に同一サーバには2つのコネクションしかできないそう(これは初めて知りました)で、asset同士のダウンロード完了するのを待たなければなりません。もし複数台のassetサーバがある場合は`assets%d.example.com`を使ってそれをコネクション数を増やせることができます。`%d`が指定されればRailsは0~3の4つの番号を付けて、並行して8つのコネクションができます。
```rubyActionController::Base.asset_host = "assets%d.example.com"```
```erbimage_tag("rails.png")# => <img alt="Rails" src="http://assets.example.com/images/rails.png?1230601161" />stylesheet_link_tag("application")# => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />```
### カスタマイズもっと自分でカスタマイズしたい場合は`source`のprocパラメータを使えます。
```rubyActionController::Base.asset_host = Proc.new { |source| "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"}image_tag("rails.png")# => <img alt="Rails" src="http://assets1.example.com/images/rails.png?1230601161" />stylesheet_link_tag("application")# => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />```
特定のパスで始まるassetを特定のホストに指定する例:```rubyActionController::Base.asset_host = Proc.new { |source| if source.starts_with?('/images') "http://images.example.com" else "http://assets.example.com" end }```
```erbimage_tag("rails.png")# => <img alt="Rails" src="http://images.example.com/images/rails.png?1230601161" />stylesheet_link_tag("application")# => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />```さらに`request`の第二パラメータもあります。これでHTTPSの動作も制御できます。
```rubyActionController::Base.asset_host = Proc.new { |source, request| if request.ssl? "#{request.protocol}#{request.host_with_port}" else "#{request.protocol}assets.example.com" end}```
## Resourceshttp://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html例えば省略可能なフラグみたいなローカル変数をpartial viewに渡した時、そのデフォルト動作をpartial viewでハンドリングしたいですね。
<%= render 'article', :show_author => false %><%= render 'article' %>
調べてみたらdefined?と local_assigns.has_key?が見つかりましたが、前者のほうはオススメできなさそうです。
Testing using defined? headline will not work. This is an implementation restriction.
# http://api.rubyonrails.org/classes/ActionView/Base.html
# If you need to find out whether a certain local variable# has been assigned a value in a particular render call, # you need to use the following pattern:
<% unless local_assigns.has_key? :show_author %> <% show_author = true %><% end %>
<% if show_author %> Author: <%= @article.author %><% end %>
# Testing using defined? headline will not work. This is an implementation restriction.
実際やってみて、defined?でも動けるパターンはありますが、if/unless文で一行にしたらバグりました。なのでやはり local_assigns.has_key?を使いましょう。
# this will work<% unless defined?(:show_author) %> <% show_author = true %><% end %>
# NOT work<% show_author = true unless defined?(:show_author) %>
# this will work<% show_author = true unless local_assigns.has_key? :show_author %>http://stackoverflow.com/questions/238615/defined-method-in-ruby-and-rails
OmniauthでTwitterに認証ログイン後、ログイン前と同じページにリダイレクトしたい
# config/application.rb
config.middleware.use 'StoreRedirectTo'
# and make sure you autoload the contents of /lib
# lib/store_redirect_to.rb
class StoreRedirectTo def initialize(app) @app = app end
def call(env) request = Rack::Request.new(env) path = request.path signin = path.match(%r(^/auth/[^/]+$)) && path != '/auth/failure' signout = path == '/users/signout' if signin || signout redirect = request.params['redirect_to'] || request.referer request.session['redirect_to'] = redirect if redirect end
@app.call(env) endend# after successful sign-in or sign-outredirect_to session[:redirect_to] || root_pathsession[:redirect_to] = nillibディレクトリのautoloadはRails libディレクトリのファイルをautoloadを参考してください。
redirect_toパラメータ或いはrefererをログイン直前のリクエストから取ってセッションに保存するRack middwareの手法です。そしてsessions_controllerではセッション内に保存されたurlにリダイレクトし、セッションクリアしています。
もちろんTwitter以外のproviderでの認証&ログイン処理にも対応できます。
# application.rb
# Custom directories with classes and modules you want to be autoloadable.# config.autoload_paths += %W(#{config.root}/extras)config.autoload_paths += %W(#{config.root}/lib)config.autoload_paths += Dir["#{config.root}/lib/**/"]サブディスプレイのautoloadが必要ない場合は一行目だけでOK.
rails serverで起動する時に盛りだくさんの情報がログに出力されるので、別ファイルで自分がデバッグしたい情報だけをそこに出力する方法です。この方法でtail -f log/custom.logで監視できます
# lib/custom_logger.rbclass CustomLogger < Logger def format_message(severity, timestamp, progname, msg) "#{timestamp.to_formatted_s(:db)} #{severity} #{msg}\n" endend
logfile = File.open("#{Rails.root}/log/custom.log", 'a') # create log filelogfile.sync = true # automatically flushes data to fileCUSTOM_LOGGER = CustomLogger.new(logfile) # constant accessible anywhere# in development.rbrequire "custom_logger"# in controller filesCUSTOM_LOGGER.info("info from custom logger")CUSTOM_LOGGER.debug("debug from custom logger")CUSTOM_LOGGER.error("error from custom logger")http://robaldred.co.uk/2009/01/custom-log-files-for-your-ruby-on-rails-applications/
http://ianma.wordpress.com/2009/04/08/custom-logging-in-ruby-on-rails/
この前Herokuのドキュメントを見ましたが、まだRails3.0.7しか正式にサポートされているようです。でも実はRails 3.1rcもherokuで実行できますよ。
### in Terminal# create rails apprails new test_app
############ start: edit Gemfile ###############wrap sqlite3 in group :test, :development dogem 'sqlite3'end
# add thin servergem 'thin'
#add the rubyracer for herokugroup :production do gem 'therubyracer-heroku', '0.8.1.pre3' gem 'pg'end
############ end: edit Gemfile ##############
### in Terminal# bundle installbundle
# git initialize git init .
# add files git commit -am "initial commit"
#create app on heroku heroku create --stack cedar
# push app to herokugit push heroku master
# test it heroku open
上記snippetはgistで保管しJavaScriptで表示しています。RSSでご覧の方は見れないと思います。お手数ですが、直接アクセスしてください。
Rails3.1.0 beta1をインストールするときにあったトラブルです。
// 3.1.0 betaに更新 sudo gem install rails --pre // バージョン確認 rails -v // ダミープロジェクト作成 rails new railsfoo // 必要なGemをインストール cd railsfoo bundle install // サーバ起動 rails s
ここまで順調でしたが、http://127.0.0.1:3000にアクセスしたときにundefined method `context’ for #
どうやらこのSprocketsというのがポイントのようです。
ぐぐってみたらgithubでこのようなコメントがありました。
Just to save someone else the 2 minutes waiting for a bundle update sprockets that will fail, beta.2 is required by rails 3.1.0beta1. You want gem ‘sprockets’, ’2.0.0.beta.2′ in your Gemfile.
のようでGemfileに下記を追記し再度bundle update。
gem 'sprockets', '2.0.0.beta.2'
解決〜
sudo gem install railsでこんなエラーが出ちゃいました。
Error installing rails bundler requires RubyGems version >= 1.3.6
解決策は
sudo gem update --system pdating RubyGems Updating rubygems-update Successfully installed rubygems-update-1.6.1 Updating RubyGems to 1.6.1 Installing RubyGems 1.6.1 RubyGems 1.6.1 installed === 1.6.1 / 2011-03-03 Bug Fixes: * Installation no longer fails when a dependency from a version that won't be installed is unsatisfied. * README.rdoc now shows how to file tickets and get help. Pull Request #40 by Aaron Patterson. * Gem files are cached correctly again. Patch #29051 by Mamoru Tasaka. * Tests now pass with non-022 umask. Patch #29050 by Mamoru Tasaka. ------------------------------------------------------------------------------ RubyGems installed the following executables: /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/gem
を実行した後にsudo gem install railsでrailsをインストールすればOKです。