Monday, October 25, 2010

Quảng cáo trên Google



Google cung cấp dịch vụ quảng cáo thông qua bộ máy tìm kiếm. 

Có 2 nguồn thông tin mà bộ máy tìm kiếm của Google sẽ tìm khi người dùng gõ một từ khóa: 
  - thông tin của Google (do Google tự tạo ra)
  - thông tin có sẵn trên internet (do người khác tạo ra, như các trang web...) 

Kết quả tìm kiếm cũng dc hiển thị theo 2 dạng dựa vào 2 nguồn thông tin trên.

Do đó, chiến lược quảng cáo trên Google cũng gồm 2 hướng:

  1. Thuê Google trực tiếp đăng quảng cáo của bạn. Google sẽ đưa thông tin của bạn vào nguồn "thông tin của Google", cái này gọi là dịch vụ Google AdWords, muốn xài cái này cần phải trả tiền, trả càng nhiều tiền thì thông tin của bạn càng dc quảng bá nhiều (tần xuất xuất hiện trên kết quả tìm kiếm trong ngày, vị trí xuất hiện,...). Cái này đòi hỏi người dùng phải có khả năng thanh toán online (Paypal, VISA card, ...) để trả tiền đăng quảng cáo cho Google. 
      Có 2 khoản cần thanh toán cho Google: 
      - Chi phí quảng cáo hằng ngày (trung bình khoảng 10$ mỗi ngày)
      - Chi phí trả cho mỗi lần có ai đó click chuột vào quảng cáo (0.001$ ???)

     Tham khảo:
     http://www.youtube.com/watch?v=tx2L6EGa9DY&feature=related

  2. Điều chỉnh thông tin của bạn (trang web) để Google dễ dàng tìm thấy (Google càng dễ tìm thấy thì trang web xuất hiện càng sớm trong kết quả tìm kiếm). Hướng này gọi là SEO (Search Engine Optimization). Hướng này đòi hỏi những điều chỉnh về mặt kĩ thuật đối với trang web của bạn sao cho thân thiện với bộ máy tìm kiếm như tối ưu hóa mã nguồn trang web, tạo nhiều liên kết từ bên ngoài tới trang web của bạn...


Monday, September 27, 2010

Ruby code snippets

1. using 'any?' to check if something in a array/hash
# a = User.all
a.any? {|user| user.name == "Hoang"}

Thursday, September 23, 2010

Some ways to refactoring Rails' code

On the following, I list some ways I found to refactoring my Rails' code. This list would be added more as time's going.

1. Method delegation
    Assume you have two models:
       + User(id, name)
       + Account(id, number, user_id)
    It could be described in Rails as:

       class User < ActiveRecord::Base
         has_many :accounts
       end
       class Account < ActiveRecord::Base
         belongs_to :user
       end

    Then if I have an Account instance named account, I could get it's user's name by: account.user.name or I can define an instance method in Account as follow:

       class Account < ActiveRecord::Base
         belongs_to :user
         
         def user_name
           user.name
         end
       end  
    Then you can get account's user name by: account.user_name. We can make the above code shorter by using delegation:

       class Account < ActiveRecord::Base
         belongs_to :user
         delegate :name, :to => :user, :prefix => true   ## this will generate user_name methods 
       end  

2. Use define_method to dynamically generate similar methods
    Given a model User(id, name, role) where role could be "admin", "moderator", "senior", "junior",... You can write instance methods to see whether a user is "admin", "moderator", ... as follow:

Before
class User < ActiveRecord::Base
  ROLES = {
    :admin => "admin",  
    :moderator => "moderator",
    :senior => "senior",
    :junior => "junior"}

    def admin?
      role == ROLES[:admin]
    end
        
    def moderator?
      role == ROLES[:moderator]
    end

    def senior?
      role == ROLES[:senior]
    end
        
    def junior?
      role == ROLES[:junior]
    end          
end
After
class User < ActiveRecord::Base
  ROLES = {
    :admin => "admin",     
    :moderator => "moderator", 
    :senior => "senior", 
    :junior => "junior"} 

    ROLES.each_pair do |key, val| 
      define_method(key.to_s + "?") { role == val}
    end
end

Friday, May 28, 2010

Ruby's origins - a find



Ruby is a pure Object-Oriented programming language. Everything in Ruby is objects, even classes. Amazing? Let's see why:

irb> 'hello'.class
=> String
irb> String.class
=> Class
irb> Array.class
=> Class
irb> Class.class
=> Class

See even further:

irb> Class.superclass
=> Module
irb> Module.superclass
=> Object
irb> Object.superclass
=> nil

irb> Module.class
=> Class
irb> Object.class
=> Class

So all classes are objects of class "Class". String, Array,.. are instances of class "Class".
Module and Object are super classes of "Class" but also instances of "Class"!!!

Tuesday, May 25, 2010

Install adva-cms on Windows

Adva-cms is an open source CMS (Content Management System) platform based on Ruby on Rails. Installing adva on Windows could be a bit tough. Follow is the steps I've tried to get passed:

1. Make sure you already installed ImageMagick and some gems adva requires

2. Just follow adva's installation guide:

# Create your app
rails my-app
cd my-app
rm public/index.html

# Prepare the config/environment.rb and remove the public/index.html
# in config/environment.rb make sure you have:
require File.join(File.dirname(__FILE__), 'boot')
require File.join(File.dirname(__FILE__), '../vendor/adva/engines/adva_cms/boot') # this line

# You *must* use Rails' old routing recognition/generation mode in order for adva-cms to work correctly:
# in config/initializers/new_rails_defaults.rb set:
ActionController::Routing.generate_best_match = true

# Clone the adva-cms ( this might take a bit, grab a coffee meanwhile :) )
git clone git://github.com/svenfuchs/adva_cms.git vendor/adva # or use: git submodule add ...

# Install the core engines and copy the assets
rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks # install adva-cms to vendor/plugins/
rake adva:assets:install # symlinks plugin assets to public/

...and get this error

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks
(in d:/Document/Projects/AdvaCMS/adva3)
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac, adva_user
rake aborted!
unknown file type: ../adva/engines/adva_activity

(See full trace by running task with --trace)

Let's trace to see why it failed:

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks --trace
(in d:/Document/Projects/AdvaCMS/adva3)
** Invoke adva:install:core (first_time)
** Execute adva:install:core
** Invoke adva:install (first_time)
** Execute adva:install
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac, adva_user
rake aborted!
unknown file type: ../adva/engines/adva_activity
c:/Ruby/lib/ruby/1.8/fileutils.rb:1256:in `copy'
c:/Ruby/lib/ruby/1.8/fileutils.rb:451:in `copy_entry'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1325:in `traverse'
c:/Ruby/lib/ruby/1.8/fileutils.rb:448:in `copy_entry'
c:/Ruby/lib/ruby/1.8/fileutils.rb:423:in `cp_r'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1396:in `fu_each_src_dest'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1405:in `fu_each_src_dest0'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1403:in `each'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1403:in `fu_each_src_dest0'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1394:in `fu_each_src_dest'
c:/Ruby/lib/ruby/1.8/fileutils.rb:422:in `cp_r'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:139:in install'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:126:in `send'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:126:in `perform'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:119:in `each'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:119:in `perform'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:35

...so there're something wrong in adva_cms.rake file. It took me a while to understand how this file does things and found the lines that caused bugs:

def source(type, subdir = nil)
"../adva/#{type}" + (subdir ? "/#{subdir}" : '')
end

...so maybe this relative path causes confusing. Let's make it full:

def source(type, subdir = nil)
"#{Rails.root}/vendor/adva/#{type}" + (subdir ? "/#{subdir}" : '')
end

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks
(in d:/Document/Projects/AdvaCMS/adva3)
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac
, adva_user
installing plugins: adva_cells
c:/Ruby/bin/rake: No such file or directory - which convert
rake aborted!
private method `chomp' called for nil:NilClass

now the engines installed ok, but there's still errors in installing plugins. It caused by paperclip initialization code that uses 'which' command to find path to 'convert' which is a tool provided by paperclip gem but 'which' command does not exist on Windows

d:/Document/Projects/AdvaCMS/adva3/vendor/plugins/adva_cms/config/initializers/p
aperclip.rb:1

Paperclip.options[:command_path] = %x[which convert].chomp.gsub(/convert/, '')

...so just go to ../vendor/adva/engines/adva_cms/config/initializers/paperclip.rb and remove 'which'

Paperclip.options[:command_path] = %x[convert].chomp.gsub(/convert/, '')

then adva's core installation gets passed!

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks
(in d:/Document/Projects/AdvaCMS/adva3)
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac
, adva_user
installing plugins: adva_cells
copied 33 migrations to db/migrate
copied 33 migrations to db/migrate/app
copied 33 migrations to db/migrate
== CreateActivitiesTable: migrating ==========================================
-- create_table(:activities, {:force=>true})
-> 0.0050s
== CreateActivitiesTable: migrated (0.0060s) =================================
...

3. Next, install adva's assets and run it up

$ rake adva:assets:install -R vendor/adva/engines/adva_cms/lib/tasks
$ script/server

...and this is what I've got


Monday, May 17, 2010

An issue with Rspec on Windows



Rspec is a very popular test framework used to test Rails application. I have tried to install and use it for my Rails projects on Windows. It raised a bug when I ran tests:
c:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:440:in load_missing_constant': uninitialized constant RbReadline::Encoding (NameError)
from c:/Ruby/lib/ruby/site_ruby/1.8/rbreadline.rb:4404 
I traced back and found these causing lines:
   if defined? ''.getbyte
      @encoding = "X"      # ruby 1.9.x or greater
      @encoding_name = Encoding.default_external.to_s
   end
It seems the Rspec uses Ruby Readline library for its command-line interface. It defined getbyte that uses Encoding module which hasn't been defined in this Ruby package on Windows. I then commented out the line using Encoding module and the bug get fixed...
   if defined? ''.getbyte
      @encoding = "X"      # ruby 1.9.x or greater
      # @encoding_name = Encoding.default_external.to_s
   end
It's not common to pass over the issue by this way but hopefully it still works fine in my case.

Monday, April 26, 2010

Hello Ruby & Rails




Ruby is a programming language and Rails (Ruby on Rails) is a web development framework written by Ruby. Those are attracting a lot of fans. Common philosophy that both Ruby and Rails based on is the simplicity, light-weight and beautifulness. You can find how easy it is to programming Ruby like talking. Also, bearing in mind with DRY (Don't Repeat Yourself) or CoC (Convention over Configuration) principles, Rails has made web developing simple and with least efforts.

Keeping track changes and sharing what I've learned from Ruby and Rails are the most important things I target to from this beginning.

So, let's say "hello Ruby & Rails"!