Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
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/
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/
Senin, 04 Juli 2011
fixing option tag display none bug in webkit
The Problem
option tag using style display:none isn't hidden in browser using webkit engine (chrome, safari)https://bugs.webkit.org/show_bug.cgi?id=8351
The workaround
using jQuery js framework with one simple function taken from jquery.extended_helper_2.6:(function($) { $.fn.extend({ /* hide select's specified option by removing the option and storing it in variable * this function is a workaround to fix webkit bug when hiding select's option: * https://bugs.webkit.org/show_bug.cgi?id=8351 * hideSelectOptions(selector, options) * selector: * - string selector of options to hide * - null or undefined will not hide any options * - empty string will hide all options * - function will be ran for all options, return true to hide the options * options: * - toggleHide: true/false, activate/deactive toggle hide/show select if all options is hidden * - placeholder: string, add placeholder option if all options is hidden * usage: * - $('select.certain_class').hideSelectOptions('.another_class'); // -> show previously hidden options and hide all options with 'another_class' class * - $('select.certain_class').hideSelectOptions(''); // -> hide all options * - $('select.certain_class').hideSelectOptions(); // -> show previously hidden options without hiding any options */ hideSelectOptions: function(selector, options){ if(!options) options = {}; this.filter('select').each(function(){ var $this = $(this); // restore previously hidden options and remove any placeholder option $this.append($this.data('hiddenOptions')).find('.placeholder_option').remove(); // return if no selector specified if(!selector) return; // find, detach and store specified hidden options var hidden_options = $this.find('option'); if($.isFunction(selector)) hidden_options = hidden_options.deleteIf(function(){return !selector.call(this);}); else hidden_options = hidden_options.filter(selector); $this.data('hiddenOptions', hidden_options .removeAttr('selected') .detach()); // find visible options var visible_options = $this.find('option'); // toggle hide/show select depend on visible option found if(options.toggleHide) $this.toggle(visible_options.length); if(options.placeholder && !visible_options.length) $this.append(''); // select first option if no other visible option selected and trigger select change if(!visible_options.filter(':selected').length){ visible_options.filter(':first').attr('selected', 'selected'); $this.trigger('change'); } }); return this; } }); })(jQuery);
The Demonstration
Kamis, 30 Juni 2011
Additional Range method
class Range # return true if 2 range overlapped def overlap? other_range include?(other_range.begin) || other_range.include?(self.begin) end # return a new intersection range between two ranges def & other_range raise TypeError, "exclusive range can't be intersected with non-exclusive one" unless self.exclude_end? == other_range.exclude_end? new_begin = [self.begin, other_range.begin].max new_end = [self.end, other_range.end].min new_begin <= new_end ? Range.new(new_begin, new_end, self.exclude_end?) : nil end # return true if other_range is a subset in self def contains? other_range if !exclude_end? include?(other_range.begin) && include?(other_range.end) elsif self.begin.respond_to?('>=') self.begin <= other_range.begin && self.end.send(other_range.exclude_end? ? '>=' : '>', other_range.end) else raise TypeError, "can't determine inclusion of range with this type of members" end end # return true if self is a subset of other_range def within? other_range other_range.contains? self end # return length of the range (only for subtract-able range) def length self.end.respond_to?('-') ? self.end - self.begin : nil end # return next range with same span (only for subtract-able and add-able range) def succ allow_touch=false return nil unless self.end.respond_to?('-') && self.end.respond_to?('+') new_begin = allow_touch || exclude_end? || !self.end.respond_to?(:succ) ? self.end : self.end.succ new_end = new_begin + length Range.new(new_begin, new_end, exclude_end?) end # return previous range with same span (only for subtract-able and add-able range) def pred allow_touch=false return nil unless self.end.respond_to?('-') && self.begin.respond_to?('+') new_end = allow_touch || exclude_end? || !self.begin.respond_to?(:pred) ? self.begin : self.begin.pred new_begin = new_end - length Range.new(new_begin, new_end, exclude_end?) end end
Selasa, 28 Juni 2011
array flatten with level for ruby 1.8.7
straight to the code:
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? ;)
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:
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:
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 :)
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:
- should avoid rescue without specifying the exception, in above code, use
rescue ActiveRecord::RecordInvalid
- better yet, don't use any rescue at all, use save instead of save! with some if
- 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:
- 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]]
- 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]
- you should check if nothing found (@something is nil)
- 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:
Too simple to become share-worthy article I guess.. :P
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
Selasa, 03 Mei 2011
Aborting AJAX Request
For some functions like autocomplete, usually we send ajax request whenever user stop typing (by using timeout), but if the request takes a long time to finish, user might sending another request while the previous one isn't done yet, in worst case scenario this might cause the requests complete order messed up therefore the result will be invalid.
We can prevent this by aborting previous ajax request before sending a new one.
XMLHttpRequest object have abort() function we can use for that purpose, documented here:
https://developer.mozilla.org/en/XMLHttpRequest#abort
in the following jquery script, i have a 2 text fields sending ajax request onkeyup that always completed in 2 seconds and adding the inputted text in the result div, the first one will have stackable ajax request, and the other one will prevent ajax request stacking by using abort
We can prevent this by aborting previous ajax request before sending a new one.
XMLHttpRequest object have abort() function we can use for that purpose, documented here:
https://developer.mozilla.org/en/XMLHttpRequest#abort
in the following jquery script, i have a 2 text fields sending ajax request onkeyup that always completed in 2 seconds and adding the inputted text in the result div, the first one will have stackable ajax request, and the other one will prevent ajax request stacking by using abort
Senin, 14 Maret 2011
cookie operation functions
function setCookie(c_name,value,exdays){ var exdate=new Date(); exdate.setDate(exdate.getDate() + exdays); var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString()); document.cookie=c_name + "=" + c_value; } function getCookie(c_name){ var i,x,y,ARRcookies=document.cookie.split(";"); for (i=0;i<ARRcookies.length;i++){ x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("=")); y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1); x=x.replace(/^\s+|\s+$/g,""); if (x==c_name){ return unescape(y); } } } function removeCookie(c_name){ setCookie(c_name, '', -1); }
Senin, 07 Maret 2011
Langganan:
Postingan (Atom)