Ruby Gems Cheat Sheet
GEM 설정
gem environment
set GEM_PATH = D:\dev\ruby192\lib\ruby\gems\1.9.1\gems
gem update --system
gem uninstall gemname
bundle update
(vendor 폴더에 bundle 설치하기)
bundle install --path vendor/bundle
devise
Controller filters and helpers
Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_filter:
before_filter :authenticate_user!
To verify if a user is signed in, use the following helper:
user_signed_in?
For the current signed-in user, this helper is available:
current_user
You can access the session for this scope:
user_session
Callbacks
after_set_user
after_authentication
before_failure
before_logout
Warden::Manager.after_authentication do |user,auth,opts|
user.last_login = Time.now
end
generator
devise g view with haml
rails g devise_views -t=haml
OmniAuth
Add :password => Devise.friendly_token[0,20] when creating a new user from facebook omniauth.
Passwords Encrypt manually
Assuming you have a mysql database with a "users" table and a "password" column And an ActiveRecord model class called "user" that is hooked up to devise
Create an ActiveRecord model class in your app app/models/old_user.rb
OldUser < ActiveRecord::Base
set_table :users
establish_connection :database => "old_database", :user => "old user", :adapter => "mysql"
end
then create a rake task: app/lib/tasks/migrate_users.rake
task :migrate_users => :environment do
OldUser.find_each do |old_user|
u = User.new(:email => old_user.email, :password => old_user.password, :password_confirmation => old_user.password);
#if your using confirmation
u.skip_confirmation!
u.save!
end
end
Modify as necessary (make sure you're saving any app-specific user attributes)
Then$ rake migrate_users
Good news and bad news.
Good news:
The following works to create your user's password manually.
pepper = nil
cost = 10
encrypted_password = ::BCrypt::Password.create("#{password}#{pepper}", :cost => cost).to_s
You can find your pepper and cost in your devise initializer. This method was confirmed using Devise's "valid_password?" method.
Bad news:
The entire reason I was trying to avoid "User.new(password: password).encrypted_password" was because of speed. It's terribly slow. With all my other pieces of my import task, I've intentionally avoided this.
But as it turns out, the major cost here is not instantiating a User object -- but BCrypt itself. There is very little noticeable speed boost when using BCrypt directly because it's intentionally designed to be slow.
My final answer: suck it up, run the rake script, go find a beverage.
mailer locale configuration
-ActionMailer::Base.default_url_options[:locale] = I18n.locale
Simple_form
<%= simple_form_for(@user, :builder => CustomBuilder) do |f| %>
<%= f.input :name %>
<% end %>
Client side validations
Client side validations Registering own form builder
https://github.com/bcardarella/client_side_validations/wiki/Registering-your-own-custom-form-builder
Client MVC
Spine
Important is only that the public directory of the application is specified
as domainroot in Confixx. If the domain is called Passenger will start automatically.."
rails g spine:model Card text is_private order user_id card_type
rails g spine:controller Cards
rails g spine:scaffold card text is_private order user_id card_type
rails g spine:model Organization title description url image admins members followers
rails g spine:controller Organizations
rails g spine:scaffold organization title description url image admins members followers
var card = App.Card.create({
is_private: true,
order: 0,
card_type: 'Reason',
text: 'Spine & Rails, sitting in a tree!'
});
straightforward way to do that without extending Spine Model's
to allow for instances to be added in memory without syncing
Ajax.disable -> saveStuff()
Model.refresh()
extends
Contact.extend(Spine.Model.Ajax);
Contact.extend({
url: '/users/'
});
'/': ->
if AuthenticatedUser
@controller = new OtherController
@replace @controller.render()
else
@controller = new LoginController
@replace @controller.render()
http://spinejs.com/docs/controller_patterns
Compass
compass init rails D:/dev/workspace/baksisi
compass init rails -r html5-boilerplate -u html5-boilerplate --syntax sass --force
css와 javascript를 asset 폴더로 옮겨준다. rails.js는 제외 (jquery_ujs와 동일하다)
Geo_location
https://github.com/chrisyour/geo_location
http://www.maxmind.com/app/geolitecountry
Mongoid id 변경하기
http://blog.joshdzielak.com/blog/2011/12/24/tame-the-mongoid-id-field-in-your-rails-and-backbone-js-app/
http://lostechies.com/derickbailey/2011/06/17/making-mongoid-play-nice-with-backbone-js/
Mongoid Follow unfollow
class User
include Mongoid::Document
field :name, type: String
has_and_belongs_to_many :following, class_name: 'User', inverse_of: :followers, autosave: true
has_and_belongs_to_many :followers, class_name: 'User', inverse_of: :following
def follow!(user)
if self.id != user.id && !self.following.include?(user)
self.following << user
end
end
def unfollow!(user)
!self.following.include?(user)
self.following.delete(user)
end
end
relation_ids instead? that is self.member_count = self.member_ids.size
self.challenged.where(_id: event.id).destroy_all
def unchallenge!(announce)
self.announcements.destroy_all( conditions: { _id: announce.id })
self.save!
end
Finally I successfully deleted the relation using self.challenged_ids.delete(event.id)
validates_inclusion_of :foo, in: [['foo'], ['bar']]
Mongoid polymorphic behaviour
When a child embedded document can belong to more than one type of parent document, you can tell Mongoid to support this by adding the as option to the definition on the parents, and the polymorphic option on the child.
class Doctor
include Mongoid::Document
embeds_one :name, as: :namable
end
class Nurse
include Mongoid::Document
embeds_one :name, as: :namable
end
class Name
include Mongoid::Document
embedded_in :namable, polymorphic: true
end
TEST
Cucumber
rails g cucumber:install ?capybara ?rspec
ruby script/rails generate cucumber:feature user email:string password:string confirm_password:string name:string nickname:string gender:integer location_name:string location:integer email_is_priavate:boolean name_is_private:boolean danted:boolean description:string
ruby script/rails generate scaffold post title:string body:text published:boolean
rake db:migrate
rake cucumber
Cucumber Errors Handling
If SystemStackError: stack level too deep
Then add gem "rspec", ">= 2.6.0.rc2", :group => [:development, :test] to Gemfile
Cucumber & Capybara Ajax
sleep second
page.driver.browser.execute_script %Q{ $('.ui-menu-item a:contains("#{link_text}")').trigger("mouseenter").click(); }
Clicking any element with Cucumber and Capybara
class Capybara::XPath
class << self
def element(locator)
append("//*[normalize-space(text())=#{s(locator)}]")
end
end
end
When 'I click "$locator"' do |locator|
msg = "No element found with the content of '#{locator}'"
locate(:xpath, Capybara::XPath.element(locator), msg).click
end
The step looks for any element with the given text. Here it is in use:
Scenario: Creating an item
Given I am signed in as "brandon@example.com"
When I click "Add to your list"
And I fill in "Description" with "blog about clicking any element"
And I press enter
Then I should see "The item was added to your list"
And I should see "blog about clicking any element"
Cucumber Capybara
selenium chrome driver
https://github.com/jnicklas/capybara
http://code.google.com/p/chromium/downloads/list
http://code.google.com/p/selenium/wiki/ChromeDriver#Overriding_the_Chrome_binary_location
Capybara.register_driver :selenium_with_firebug do |app|
Capybara::Driver::Selenium
profile = Selenium::WebDriver::Firefox::Profile.new
profile.add_extension(File.expand_path("features/support/firebug-1.6.0-fx.xpi"))
Capybara::Driver::Selenium.new(app, { :browser => :firefox, :profile => profile })
end
Before("@selenium_with_firebug") do
Capybara.current_driver = :selenium_with_firebug
end
I18n
I18n-js initialize
layout/application.html.haml
- html_tag :class => 'no-js', :lang => "#{I18n.locale}"
applcation.js
I18n.default_locale = "en"
I18n.locale = $($("html")[0]).prop("lang")
I18n.fallbacks = true
Media - Flickraw
flickr.upload_photo(params[:photo].tempfile.path)
Gem Trouble shooting
Q. `require': no such file to load -- thin (LoadError)
A. => Add gem 'thin' to Gemfile
Rails Performance
- Curb for Http (libcurl)
- Yajl, the fastest JSON library.
- excon #=> faster http
- Nokogiri, the fastest XML library.
- Snappy, super fast compression tool by google.
- fast_xs
- Memcache. (libmemcached)
- use Ree Garbage Collector
Fastest Server
- Unicorn
- Thin
Profiling Tools
- NewRelic - Monitoring Tool (Commercial)
- Ganglia - Monitoring Tool (OpenSource)
- Cloudflare - Performance & Security
- rack-perftools
Rack-bug
1. Install rack-bug (branch rails3) as plugin
cd vendor/plugins
git clone -b rails3 https://github.com/brynary/rack-bug.git
If you want to you it as gem then add following line into Gemfile
gem 'rack-bug', :git => 'https://github.com/brynary/rack-bug.git', :branch => 'rails3'
2. Replace the code from file actionview_extension.rb
which is avilable in vendor/plugins/rack-bug/lib/rack/bug/panels/templates_panel/ as specified in bug of rack_bug repository
if defined?(ActionView) && defined?(ActionView::Template)
ActionView::Template.class_eval do
def render_with_rack_bug(*args, &block)
Rack::Bug::TemplatesPanel.record(virtual_path) do
render_without_rack_bug(*args, &block)
end
end
alias_method_chain :render, :rack_bug
end
end
If you are using gem override the specified file in some way
3. Add following lines into your config.ru
require 'rack/bug'
use Rack::Bug, :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring"
run myapp
4. Start your server and access the URL http://your_app/__rack_bug__/bookmarklet.html
and enter the password.
http://blog.railsupgrade.com/2011/04/configure-rack-bug-for-rails-3.html
출처
- 직접 작성
- rubygems.org
- Stack Overflow
- google 검색
by 月風