Halaman

Tampilkan postingan dengan label rails. Tampilkan semua postingan
Tampilkan postingan dengan label rails. Tampilkan semua postingan

Jumat, 11 April 2014

Rails (Rack::Utils) HTTP Status Codes and Symbols

ruby -e 'require "rack/utils"; puts Rack::Utils::SYMBOL_TO_STATUS_CODE.map{|s,c| "|" + c.to_s.center(5) + "|" + s.inspect.center(60) + "|" + Rack::Utils::HTTP_STATUS_CODES[c].to_s.center(60) + "|"}.join("\n")'
| 100 |                         :continue                          |                          Continue                          |
| 101 |                    :switching_protocols                    |                    Switching Protocols                     |
| 102 |                        :processing                         |                         Processing                         |
| 200 |                            :ok                             |                             OK                             |
| 201 |                          :created                          |                          Created                           |
| 202 |                         :accepted                          |                          Accepted                          |
| 203 |               :non_authoritative_information               |               Non-Authoritative Information                |
| 204 |                        :no_content                         |                         No Content                         |
| 205 |                       :reset_content                       |                       Reset Content                        |
| 206 |                      :partial_content                      |                      Partial Content                       |
| 207 |                       :multi_status                        |                        Multi-Status                        |
| 208 |                     :already_reported                      |                      Already Reported                      |
| 226 |                          :im_used                          |                          IM Used                           |
| 300 |                     :multiple_choices                      |                      Multiple Choices                      |
| 301 |                     :moved_permanently                     |                     Moved Permanently                      |
| 302 |                           :found                           |                           Found                            |
| 303 |                         :see_other                         |                         See Other                          |
| 304 |                       :not_modified                        |                        Not Modified                        |
| 305 |                         :use_proxy                         |                         Use Proxy                          |
| 306 |                         :reserved                          |                          Reserved                          |
| 307 |                    :temporary_redirect                     |                     Temporary Redirect                     |
| 308 |                    :permanent_redirect                     |                     Permanent Redirect                     |
| 400 |                        :bad_request                        |                        Bad Request                         |
| 401 |                       :unauthorized                        |                        Unauthorized                        |
| 402 |                     :payment_required                      |                      Payment Required                      |
| 403 |                         :forbidden                         |                         Forbidden                          |
| 404 |                         :not_found                         |                         Not Found                          |
| 405 |                    :method_not_allowed                     |                     Method Not Allowed                     |
| 406 |                      :not_acceptable                       |                       Not Acceptable                       |
| 407 |               :proxy_authentication_required               |               Proxy Authentication Required                |
| 408 |                      :request_timeout                      |                      Request Timeout                       |
| 409 |                         :conflict                          |                          Conflict                          |
| 410 |                           :gone                            |                            Gone                            |
| 411 |                      :length_required                      |                      Length Required                       |
| 412 |                    :precondition_failed                    |                    Precondition Failed                     |
| 413 |                 :request_entity_too_large                  |                  Request Entity Too Large                  |
| 414 |                   :request_uri_too_long                    |                    Request-URI Too Long                    |
| 415 |                  :unsupported_media_type                   |                   Unsupported Media Type                   |
| 416 |              :requested_range_not_satisfiable              |              Requested Range Not Satisfiable               |
| 417 |                    :expectation_failed                     |                     Expectation Failed                     |
| 422 |                   :unprocessable_entity                    |                    Unprocessable Entity                    |
| 423 |                          :locked                           |                           Locked                           |
| 424 |                     :failed_dependency                     |                     Failed Dependency                      |
| 425 | :reserved_for_webdav_advanced_collections_expired_proposal | Reserved for WebDAV advanced collections expired proposal  |
| 426 |                     :upgrade_required                      |                      Upgrade Required                      |
| 509 |                        :unassigned                         |                         Unassigned                         |
| 428 |                   :precondition_required                   |                   Precondition Required                    |
| 429 |                     :too_many_requests                     |                     Too Many Requests                      |
| 431 |              :request_header_fields_too_large              |              Request Header Fields Too Large               |
| 500 |                   :internal_server_error                   |                   Internal Server Error                    |
| 501 |                      :not_implemented                      |                      Not Implemented                       |
| 502 |                        :bad_gateway                        |                        Bad Gateway                         |
| 503 |                    :service_unavailable                    |                    Service Unavailable                     |
| 504 |                      :gateway_timeout                      |                      Gateway Timeout                       |
| 505 |                :http_version_not_supported                 |                 HTTP Version Not Supported                 |
| 506 |         :"variant_also_negotiates_(experimental)"          |           Variant Also Negotiates (Experimental)           |
| 507 |                   :insufficient_storage                    |                    Insufficient Storage                    |
| 508 |                       :loop_detected                       |                       Loop Detected                        |
| 510 |                       :not_extended                        |                        Not Extended                        |
| 511 |              :network_authentication_required              |              Network Authentication Required               |

Sabtu, 06 Juli 2013

Sharing gems (or any files really) from lubuntu to windows

Continuing from my previous post about developing rails using lubuntu vm as rails server, I need to have access to gem files inside lubuntu from windows for viewing its sources..

At first I tried to use virtual box shared folders to store rbenv/gems files but it cause many problems in ruby or at the very least it result in a very slow performance (especially when gems are loading)

After many many sleepless nights (dramatization) I finally succeed by using samba and sharing the gems via (virtual) network with the following steps..

Jumat, 28 Juni 2013

Developing Rails in Windows using Linux Server



Developing rails/ruby app in windows is painful as many gems aren't compatible or optimized for windows. But windows is OS that I'm most comfortable with.. Linux (ubuntu) lack some tools that I need and I simply hate OSX (stupid keyboard layout and hardware restriction), so I prefer dealing with gem problems rather than changing OS..

But then it occurred to me, why not just use virtual machine with linux for server? And turns out it's pretty neat.. And I think some people are too use windows as main OS so I posted here the step for setting up linux vm for rails..

Sabtu, 24 November 2012

Sublime Text 2: jump to definition

Since I moved from netbeans (which no longer officially support rails) to sublime text 2, the only thing that I missed is jump to definition function, often when I need to know how certain method from a gem works I'm forced to search it manually inside that gem folder while on netbeans I can just use alt+click to instantly navigate there..

After some googling I found SublimeCodeIntel which most of the time isn't working and make sublime heavier instead. But at long last I found about CTags and a Sublime Package for it.

First you need to build the tags file by using Rebuild Tags from command palette, after that using it is pretty much similar to netbeans, but instead of alt+click we use ctrl+shift+click plus ctrl+shift+rightclick for returning to previous position and it's works perfectly... for methods inside the project..

Sublime CTags readme show a script to generate tags for gems which is works perfectly, it will generate tags from all gems specified in Gemfile, but adding the script each time I work on a project is kinda troublesome so I created a simple gem to add several rake tasks for generating tags. The gem basically add 3 rake tasks, one for generating tags for project, one for gems, and the last one for both project and gems.

Rabu, 24 Oktober 2012

Rails setup in linode

  1. Login to linode
  2. choose linux distribution (ubuntu)
  3. allocate disk space and swap
  4. boot
  5. remote access using ssh
  6. apt-get update
    apt-get upgrade --show-upgraded
  7. set hostname:
    echo "ayahirano" > /etc/hostname
    hostname -F /etc/hostname
  8. nano /etc/hosts
    127.0.0.1 localhost.localdomain localhost
    12.34.56.78 ayahirano.invalid  hirano
    2600:3c01::a123:b456:c789:d012 ayahirano.invalid hirano
  9. set timezone to UTC:
    dpkg-reconfigure tzdata
  10. install required libs:
    apt-get install build-essential zlib1g-dev libssl-dev libreadline6-dev libxslt1-dev libcurl4-openssl-dev apache2-mpm-prefork apache2-prefork-dev libapr1-dev libaprutil1-dev git-core
  11. install require lib for postgresql (optional):
    apt-get install postgresql postgresql-contrib libpq-dev
  12. create new user:
    adduser example_user
    usermod -a -G sudo example_user
  13. logout and relogin user the new user
  14. disable root login:
    sudo nano /etc/ssh/sshd_config
    PermitRootLogin no
  15. setup postgresql (optional):
    sudo -u postgres createuser --superuser example
    sudo -u postgres psql postgres
    \password example
    \q
    sudo nano /etc/postgresql/8.4/main/postgresql.conf:
    listen_addresses = 'localhost'
    sudo nano /etc/postgresql/8.4/main/pg_hba.conf:
    local       all        all                      md5
    sudo /etc/init.d/postgresql start
  16. install rvm:
    \curl -L https://get.rvm.io | bash -s stable
    source /home/example_user/.rvm/scripts/rvm
  17. install ruby:
    rvm install ruby
  18. disable gem documentation installation:
    nano ~/.gemrc
    gem: --no-ri --no-rdoc
  19. install passenger:
    gem install passenger
    rvmsudo passenger-install-apache2-module
  20. get your app to /var/www/example
  21. disable default virtual host:
    sudo a2dissite default
  22. create new virtual host config:
    sudo nano /etc/apache2/sites-available/example
    <VirtualHost *:80>
      ServerName ayahirano.invalid
      ServerAlias *.ayahirano.invalid
      RailsEnv production
      DocumentRoot /var/www/example/public

      <Directory /var/www/
    example/public>
        AllowOverride all
        # MultiViews must be turned off.
        Options -MultiViews
      </Directory>
    </VirtualHost>
  23. enable it:
    sudo a2ensite example
  24. edit apache configuration file:
    sudo nano /etc/apache2/mods-available/passenger.load
    LoadModule passenger_module /home/rails/.rvm/gems/ruby-1.9.3-p286/gems/passenger-3.0.17/ext/apache2/mod_passenger.so
    sudo nano /etc/apache2/mods-available/passenger.conf
    PassengerRoot /home/rails/.rvm/gems/ruby-1.9.3-p286/gems/passenger-3.0.17
    PassengerRuby /home/rails/.rvm/wrappers/ruby-1.9.3-p286/ruby
  25. enable passenger module:
    sudo a2enmod passenger
  26. restart apache:
    sudo service apache2 restart

Extras

Installing nodejs for js runtime (needed by assets precompile):


https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager

Creating deploy script

  1. cd $HOME
  2. nano deploy.sh
  3. #!/bin/sh
    sudo echo -n "precompile assets? (y or n) : "
    read precompile
    echo -n "bundle install? (y or n) : "
    read bundler
    cd /var/www/example
    git pull
    if [ $bundler = y -o $bundler = Y -o $bundler = yes -o $bundler = Yes -o $bundler = YES ]; then
      bundle install --without development test
    fi
    if [ $precompile = y -o $precompile = Y -o $precompile = yes -o $precompile = Yes -o $precompile = YES ]; then
      bundle exec rake assets:precompile RAILS_ENV=production
    fi
    rake db:migrate RAILS_ENV=production
    # any other thing you do when deploying...
    sudo service apache2 restart
  4. chmod 700 deploy.sh
  5. Done.. To run use: ./deploy.sh

Minggu, 01 Januari 2012

using compass in rails 3.1.3

group :assets do
  gem 'sass-rails',   '~> 3.1.5'
  gem 'coffee-rails', '~> 3.1.1'
  gem 'uglifier', '>= 1.0.3'
  gem 'compass', '>= 0.12.alpha'
end

config.assets.precompile << /(^[^_]|\/[^_])[^\/]*$/

Sabtu, 31 Desember 2011

ubuntu 11.10 rails 3 passenger

http://ubuntuandrails.blogspot.com/2011/11/installing-rails-311-ruby-193-apache2.html

Senin, 03 Oktober 2011

install mysql2 > 0.3.6 for mysql 64bit in windows

gem install mysql2 --platform=ruby -- '--with-mysql-lib="C:\Program Files\MySQL\MySQL Server 5.5\lib" --with-mysql-include="C:\Program Files\MySQL\MySQL Server 5.5\include"'

http://dev.mysql.com/downloads/connector/c/

copy  C:\mysql-connector-c-noinstall-6.0.2-win32\lib\libmysql.dll to ruby\bin

original source: http://blog.mmediasys.com/2011/07/07/installing-mysql-on-windows-7-x64-and-using-ruby-with-it/

Selasa, 28 Juni 2011

array flatten with level for ruby 1.8.7

straight to the code:
class Array
  alias_method :orig_flatten, :flatten
  
  def flatten level=nil
    if level.is_a?(Integer)
      temp_arr = clone
      level.times{ |i| temp_arr = temp_arr.inject([]){|s,v| v.is_a?(Array) ? s.concat(v) : s << v} }
      temp_arr
    else
      orig_flatten
    end
  end
end

of course although untested i'm sure it will have worse performance than the original flatten in ruby 1.9.2, but better than nothing right? ;)

ruby array to hash method

update 2012-12-21:
you should use flat_map instead of flatten, i'm too lazy to update the code though.. :P

we can convert hash to array easily using .to_a method for example:
hsh = {:a => 1, :b => 2, :c => 3}
arr = hsh.to_a # -> [[:a, 1], [:b, 2], [:c, 3]]

but there's no built in method to reverse that, there's no .to_hash instance method for array.

to solve that i added a simple instance method for array:
class Array
  def to_hash values=nil
    Hash[*(values.is_a?(Array) ? self.zip(values) : self).flatten(1)]
  end
end

hsh = {:a => 1, :b => 2, :c => 3}
arr = hsh.to_a # -> [[:a, 1], [:b, 2], [:c, 3]]
arr.to_hash == hsh # -> true
[:a,:b,:c].to_hash [1,2,3] # -> {:a => 1, :b => 2, :c => 3}

a little precaution, flatten(1) will not work properly in ruby 1.8.7 or older, therefore it won't be possible to create hash with array as key or value. but there's a simple workaround for that by overriding array flatten method to behave like ruby 1.9.2 in my next post :)

useful online tools for web programming

  • Regex for ruby: http://www.rubular.com/
  • strftime: http://strfti.me/
  • css gradient generator: http://www.colorzilla.com/gradient-editor/
  • css validator: http://jigsaw.w3.org/css-validator/
  • css rounder corner generator: http://a.deveria.com/roundgen/
  • 7 great js resources (not really a tool but useful): http://mashable.com/2011/07/03/7-great-javascript-resources

will be updated as i found another tools

Sabtu, 11 Juni 2011

Rails general coding style

Code:

# somethings_controller.rb
def create
  @something = Something.new params[:something]
  @something.save!
  if @something.some_state?
    @something.initialize_for_some_state
  end
  redirect_to success_url
rescue
  render :action => "failed"
end

Hint:

  1. should avoid rescue without specifying the exception, in above code, use
    rescue ActiveRecord::RecordInvalid
  2. better yet, don't use any rescue at all, use save instead of save! with some if
  3. post processing should be done in callback.
    after_create {|something| something.initialize_for_some_state if something.some_state}

Better Code:

# somethings_controller.rb
def create
  @something = Something.new params[:something]
  if @something.save
    redirect_to success_url
  else
    render :action => "failed"
  end
end

Code:

# somethings_controller.rb
def show
  @something = Something.find(:first, :conditions => "user_id = #{current_user.id} AND id = #{params[:id]} AND name = #{params[:name]}")
  respond_to do |format|
    format.html
    format.js do
      render :js => "$('#container').html('#{escape_javascript(render :partial => "something", :object => @something)}');"
    end
    format.json do
      render :json => @something.to_json
    end
  end
end

Hint:

  1. SQL injection warning! never use data from params or from user input directly in sql code. use something like this instead:
    :conditions => ["user_id = #{current_user.id} AND id = ? AND name = ?", params[:id], params[:name]]
  2. using model relation and dynamic finder you can avoid the conditions entirely
    @something = current_user.somethings.find_by_id_and_name params[:id], params[:name]
  3. you should check if nothing found (@something is nil)
  4. this is just my opinion, but in most case i'll avoid using respond_to, instead i'll use 3 different view files: show.html.erb, show.js.erb, show.json.erb. rails will automatically use the correct view.

Better Code:

# somethings_controller.rb
def show
  @something = current_user.somethings.find_by_id_and_name params[:id], params[:name]
  render_invalid "not found" if @something.nil? # read about render_invalid in http://tech.maysora.com/2010/12/rails-renderinvalid-method.html
end


to be continued about model

Rabu, 01 Juni 2011

Counting sub-string occurrence in a string

Once upon a time.. I need a way to count number of occurrence of certain sub-string (not exclusively words) inside a string.

For example, string "Aya Hirano is the best seiyuu in the world! She was mostly known as her role as Haruhi." I wanted to know how many times string "he" occurred in there.
The result should be 4, 2 in the, 1 in She and 1 in her.

By using scan method we can do that easily:
class String
  def substr_count(pattern)
    self.scan(pattern).length
  end
end

"Aya Hirano is the best seiyuu in the world! She was mostly known as her role as Haruhi.".substr_count("he") # -> 4
"Aya Hirano is the best seiyuu in the world! She was mostly known as her role as Haruhi.".substr_count(/(!|\.|\?)/) # -> 2 -> counting sentences? :D

Too simple to become share-worthy article I guess.. :P

Rabu, 22 Desember 2010

[shared] change rails form error field wrapper

by default rails wrap all fields that contain error data using div with "fieldWithErrors" class

but sometimes we want to change that wrapper for example to use span instead of div.
that can easily be done by overriding field_error_proc class attribute in ActionView::Base

in environment.rb
ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}".html_safe }

file position (for rails 2.3.10):
[ruby_dir]\lib\ruby\gems\1.8\gems\actionpack-2.3.10\lib\action_view\helpers\active_record_helper.rb

[shared] rails render_invalid method

purpose


provide DRY solution for rendering (or redirecting) from controller on invalid request, such as failed validation on create/update

requirements


- jquery js framework
- notifications helper from my earlier post about custom ajax helper:
http://tech.maysora.com/2010/11/rails-custom-ajax-helper-for-jquery.html

codes


application_controller.rb
# render invalid request to show error message depend on request type
# example:
#   render_invalid "Update failed."
#     ajax: show error notification with message "Update failed."
#     html: simply render text "Update failed."
#   render_invalid "Save failed.", :render => {:action => "new"}
#     ajax: show error notification with message "Save failed."
#     html: render action new with "Save failed." flash message
#   render_invalid "Save failed.", :render => {:action => "new"}, :flash => false
#     same as above but without flash for html
#   render_invalid "You can't do that.", :redirect_to => {:action => "index"}, :flash => false, :status => :unauthorized
#     same as above but redirecting to index instead of rendering new for html
#     and using unauthorized(401) status instead of not_acceptable(406)
#   render_invalid "Update failed.", :object => @user, :fields_wrapping => true
#     ajax: show error notification with addition of object's error messages and wrap error fields with div class fieldWithErrors
#     html: same as ajax minus fields wrapping
def render_invalid message="Error.", options={:flash => true}
  options[:status] ||= :not_acceptable
  message += "
#{options[:object].errors.full_messages.join(' ')}
" if options[:object].present? respond_to do |format| format.js do render(:update, :status => options[:status]) do |page| page << notification_error(message) if options[:object].present? && options[:fields_wrapping] page.rjs_clean_error_fields request page.rjs_apply_error_fields options[:object], request end end end format.html do if options[:render].present? flash.now[:error] = message if options[:flash] render options[:render].try(:merge, {:status => options[:status]}) || {:text => message, :status => options[:status]} elsif options[:redirect_to].present? flash[:error] = message if options[:flash] redirect_to options[:redirect_to] else render :text => message, :status => options[:status] end end end end

application_helper.rb (only if you use ajax error fields wrapping)
def rjs_apply_error_fields object, request
  klass_name = object.class.name.underscore
  wrapper = "
" object.errors.each do |attr, msg| attr = attr.split(".") page << "var $fields = $(), $container = $('\##{klass_name}_#{object.id || "new"}');" page << "if(!$container.length) $container = $('form[action=\\'#{request.request_uri}\\']');" page << "if(!$container.length) $container = $(document);" if attr.length > 1 object.send(attr.first).each_with_index do |x,i| page << "$fields = $fields.add('[id^=#{klass_name}_#{attr.first}_attributes][id$=#{attr.last}]:eq(#{i}),label[for^=#{klass_name}_#{attr.first}_attributes][for$=#{attr.last}]:eq(#{i})', $container)" if x.errors.on(attr.last) end else page << "$fields = $('label[for=#{klass_name}_#{attr}],\##{klass_name}_#{attr}', $container);" end page << "if(!$fields.parent('.fieldWithErrors').length)" page << "$fields.wrap('#{wrapper}')" end end def rjs_clean_error_fields request page << "$('.fieldWithErrors.rjs_#{request.request_method}_#{request.request_uri.gsub(/_=\d+($|&)/, "").parameterize} *').unwrap();" end

usage

users_controller.rb (using non ajax form)
#...

def create
  @user = User.new(params[:user])
  unless @user.save
    render_invalid "Failed to register.", :object => @user, :render => {:action => "new"}
  else
    flash[:info] = "Registration success, please check your email to activate."
    redirect_to login_path
  end
end

#...
users_controller.rb (using ajax form)
#...

def update
  @user = current_user
  unless @user.update_attributes(params[:user])
    render_invalid "Profile update failed.", :object => @user, :fields_wrapping => true
  end
end

#...
and update.js.rjs (for success behavior)
page << notification_info "Profile updated."
page.rjs_clean_error_fields request # used for cleaning error fields wrapping
#... other necessary action ...

additional tips

depending on your site style, it might be a good idea to change the div wrapper in rjs_apply_error_fields helper to span. you can also change rails standard error field wrapper for non-ajax form, see this post

Minggu, 21 November 2010

[shared] rails custom ajax helper for jquery

requirements:
- jrails plugin (https://github.com/aaronchi/jrails)
- working jquery.gritter or other js notification (http://boedesign.com/blog/2009/07/11/growl-for-jquery-gritter/)
- my jquery.extended_helper (http://code.google.com/p/jquery-extendedhelper)

installation:
- add these code in application_helper.rb
# Adding additional options for ajax function
# You can use thisElement to manipulate element that using the function (link/button/form)
def custom_remote_function_options options
  options[:before] ||= ""
  options[:loading] ||= ""
  options[:complete] ||= ""
  options[:success] ||= ""
  options[:before] += "; var thisElement=this"
  options[:failure] ||= "; eval(request.responseText)"

  unless options[:loading_text].blank?
    options[:loading] += "; thisElement.notif = #{notification_loading(options[:loading_text])}"
    options[:complete] += "; #{notification_remove "thisElement.notif"}"
  end
  options
end

# Override rails remote_function using additional options
def custom_remote_function options
  remote_function(custom_remote_function_options(options)).html_safe
end

# Override rails link_to_remote function using additional options
# Disabling the link when ajax loading in progress to avoid double request
def custom_link_to_remote name, options={}, html_options=nil
  options = custom_remote_function_options options
  options[:loading] += "; $(thisElement).setLink(false)"
  options[:complete] += "; $(thisElement).setLink(true)"
  link_to_remote name, options, html_options
end

# Override rails button_to_remote function using additional options
# Disabling the button when ajax loading in progress to avoid double request
def custom_button_to_remote name, options={}, html_options=nil
  options = custom_remote_function_options options
  options[:loading] += "; $(thisElement).setInput(false)"
  options[:complete] += "; $(thisElement).setInput(true)"
  button_to_remote name, options, html_options
end

# Adding additional options for ajax form
# Add :unchange_default => true to prevent successful request changing default form fields value
# Add :disable_link => true to disable all link inside form when loading in progress
def custom_remote_form_options options
  options = custom_remote_function_options options
  options[:loading] += "; $(':input', thisElement).setInput(false);"
  options[:complete] += "; $(':input', thisElement).setInput(true);"
  unless options[:unchange_default]
    options[:success] +=  "; $(':input', thisElement).setDefault();"
  end
  if options[:disable_link]
    options[:loading] += "; $('a', thisElement).setLink(false);"
    options[:complete] += "; $('a', thisElement).setLink(true);"
  end
  options
end

# Override rails remote_form_for using additional options
def custom_remote_form_for record_or_name_or_array, *args, &proc
  args.push custom_remote_form_options(args.extract_options!)
  remote_form_for record_or_name_or_array, *args, &proc
end
alias_method :custom_form_remote_for, :custom_remote_form_for

# Override rails form_remote_tag using additional options
def custom_form_remote_tag options={}, &block
  form_remote_tag custom_remote_form_options(options), &block
end
alias_method :custom_remote_form_tag, :custom_form_remote_tag

def custom_button_to_remote name, value, options = {}
  button_to_remote name, value, custom_remote_form_options(options)
end

# Override rails submit_to_remote using additional options
def custom_submit_to_remote(name, value, options = {})
  submit_to_remote(name, value, custom_remote_form_options(options))
end

def notification_info text, no_escape=false
  text.gsub!(/\n/, '
')
  text = escape_javascript(text) unless no_escape
  "notificationInfo('#{text}')"
end

def notification_loading text, no_escape=false
  text.gsub!(/\n/, '
')
  text = escape_javascript(text) unless no_escape
  "notificationLoading('#{text}')"
end

def notification_error text, no_escape=false
  text.gsub!(/\n/, '
')
  text = escape_javascript(text) unless no_escape
  "notificationError('#{text}')"
end

def notification_remove notification
  "notificationRemove(#{notification})"
end

- add notification code in application.js (sample using jquery.gritter)
function notificationInfo(text){
  return $.gritter.add({text: text.replace(/\n/g, '
')});
}

function notificationError(text){
  return $.gritter.add({text: '' + text.replace(/\n/g, '
') + '',time: 6000});
}

function notificationLoading(text){
  return $.gritter.add({text: text.replace(/\n/g, '
'), image: '/images/gritter-loading.gif', sticky:true})
}

function notificationRemove(notification){
  $.gritter.remove(notification);
}

rails http status code and symbol

Status CodeStatus MessageSymbol
1xx Informational
100Continue:continue
101Switching Protocols:switching_protocols
102Processing:processing
 
2xx Success
200OK:ok
201Created:created
202Accepted:accepted
203Non-Authoritative Information:non_authoritative_information
204No Content:no_content
205Reset Content:reset_content
206Partial Content:partial_content
207Multi-Status:multi_status
226IM Used:im_used
 
3xx Redirection
300Multiple Choices:multiple_choices
301Moved Permanently:moved_permanently
302Found:found
303See Other:see_other
304Not Modified:not_modified
305Use Proxy:use_proxy
307Temporary Redirect:temporary_redirect
 
4xx Client Error
400Bad Request:bad_request
401Unauthorized:unauthorized
402Payment Required:payment_required
403Forbidden:forbidden
404Not Found:not_found
405Method Not Allowed:method_not_allowed
406Not Acceptable:not_acceptable
407Proxy Authentication Required:proxy_authentication_required
408Request Timeout:request_timeout
409Conflict:conflict
410Gone:gone
411Length Required:length_required
412Precondition Failed:precondition_failed
413Request Entity Too Large:request_entity_too_large
414Request-URI Too Long:request_uri_too_long
415Unsupported Media Type:unsupported_media_type
416Requested Range Not Satisfiable:requested_range_not_satisfiable
417Expectation Failed:expectation_failed
422Unprocessable Entity:unprocessable_entity
423Locked:locked
424Failed Dependency:failed_dependency
426Upgrade Required:upgrade_required
 
5xx Server Error
500Internal Server Error:internal_server_error
501Not Implemented:not_implemented
502Bad Gateway:bad_gateway
503Service Unavailable:service_unavailable
504Gateway Timeout:gateway_timeout
505HTTP Version Not Supported:http_version_not_supported
507Insufficient Storage:insufficient_storage
510Not Extended:not_extended

source: http://www.codyfauser.com/2008/7/4/rails-http-status-code-to-symbol-mapping

Rabu, 17 November 2010

[shared] array/hash support for system_settings

https://github.com/realityforge/rails-system-settings

# system_settings/lib/system_setting.rb

class SystemSetting < ActiveRecord::Base
@@data = {}

validates_length_of :name, :in => 1..255
validates_uniqueness_of :name

serialize :value

def self.[](name)
name = name.to_s unless name.is_a? String
return @@data[name] unless @@data[name].nil?
p = SystemSetting.find_by_name(name)
@@data[name] = p ? p.value.freeze : nil
end

def self.[]=(name, value)
name = name.to_s unless name.is_a? String
p = SystemSetting.find_or_initialize_by_name(name)
@@data[name] = p.value = value
p.save!
p.value.freeze
end
end

[shared] Unsigned int support for migration

currently rails only allow signed int for migration, but for best practice it's better to use unsigned int for some cases

you can force migration to unsigned int by doing something like this

t.column :unsigned_value, "integer unsigned"


but that kinda ugly to see.
luckily rob anderton (thewebfellas.com) already created monkey patch to add unsigned support: http://thewebfellas.com/assets/2008/9/30/active_record_unsigned.rb

the patch will add :unsigned option in migration so you can do something like this:

t.integer :unsigned_value, :unsigned => true


furthermore the patch will make default table id and foreign key to unsigned int(11), but make sure to use t.references to create foreign key or simply use :unsigned => true

important things:


- for existing project this patch might break table relation because it will create unsigned int foreign key but the primary key might be signed int from old migration
- some plugin like role_requirement will generate migration that using t.integer for foreign key instead of t.references, you need to change this manually
- the patch will only change mysql adapter, so it will not work for other adapter

[shared] Rails migration integer limit

:limit Numeric Type Column Size Signed Max value Unsigned Max value
1 TINYINT(4) 1 byte 127 255
2 SMALLINT(6) 2 bytes 32767 65535
3 MEDIUMINT(9) 3 bytes 8388607 16777215
4 and others INT(11) 4 bytes 2147483647 4294967295
5..8 BIGINT(20) 8 bytes 9223372036854775807 18446744073709551615