Tips – Print test name and file name when testing (update)

Posted by AllenWei | Posted in RubyOnRails, Tips | Posted on 14-04-2010-05-2008

View Comments




<breprecated-

See this tips-print-test-name-and-file-name-when-testing-final-solution

Last time to introduced how to print test name and method when tesing

I found it actually have problem, it can’t print test name when some testcase implement setup method. alias_method_chain will not work.

Then I discovered we have a way to work around, last blog post mentioned Wrap a method which might be overrided by subclass

So I’ll changed the code a bit like this:

class ActiveSupport::TestCase
  def self.inherited(base)
    base.class_eval do
      def setup_with_naming
        puts "\n== #{@method_name} : #{self.class.name} =="
        setup_without_naming        
      end

      def setup
       
      end

      def self.method_added(meth)
        return if @_in_method_added
        @_in_method_added = true
        if meth.to_s == "setup"
          alias_method_chain :setup, :naming
        end
        @_in_method_added = false
      end
    end
  end
end


Tips – Merge ActiveRecord Condtions

Posted by AllenWei | Posted in RubyOnRails, Tips | Posted on 01-04-2010-05-2008

View Comments

Assuming We have Member model.
And one record with name Hnery Miller, with state draft

I have two conditions:

condition1 = ['name like ?','Hnery%']
condition2 = ['state = ?','draft']

What I gonna do is merge these two conditions, using Rails ActiveRecord buildin method merge_conditions

Member.first(:conditions => Member.merge_conditions(condition1,condition2))

Rails Configuration Load Order

Posted by AllenWei | Posted in RubyOnRails, Tips | Posted on 30-03-2010-05-2008

View Comments

As this blog post said.

Rails configuration load order is:

  1. config/preinitializer.rb
  2. config/environment.rb
  3. config/environments/#{RAILS_ENV}.rb
  4. plugin initialization
  5. gem initialization
  6. config/initializer/*.rb
  7. all after_initialize blocks, in the order they were defined in (so same order as above)
  8. any junk left below the Rails::Initializer.run call/block in environment.rb

Tips – Send method into Active Record

Posted by AllenWei | Posted in RubyOnRails, Tips | Posted on 30-03-2010-05-2008

View Comments

If you want to enhance ActiveRecord, what you need do?

Write a piece of code in lib like this

# Usage
# =========
# class SomeModel
#   money :amount,:consideration_value
# end
#
# options
# ========
# precision => 2
# delimiter => ","
module Moneyable
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    include ::CurrencyRounding
    def money(*names)
      include CurrencyRounding
      if names.last.kind_of?(Hash)
        options = names.pop
      else
        options = {}
      end
      cattr_accessor :variables_need_format
      names.each do  |name|
        self.variables_need_format ||= []
        self.variables_need_format << name.to_sym
        define_method "formatted_#{name.to_s}" do
          nice_rounding_with_format(send(name),options)
        end
      end
    end
  end
end

Then Hack AcitveRecord
puts code below in enviroment.rb

# in 'Rails::Initializer.run do |config|' block
# if there is 'no config.after_initialize'
 config.after_initialize do
    ActiveRecord::Base.send(:include, Moneyable)
 end

The missing guide of rails 2 generator part 2

Posted by AllenWei | Posted in RubyOnRails | Posted on 18-02-2010-05-2008

View Comments

Last post The missing guide of rails 2 generator part 1 I showed you the basic knowledge about rails generator.

This post I’ll show you another type of generator Named Geneerator

What’s the different between basic generator and named generator?

Commonly it used by this kind of generate script/generate generator_name hello attr1:value1

  1. named generator will get first argument you passed in as name attribute, and what’s more it convert name to 3 types of string plural_name,singular_name,table_name
  2. For the reset of attributes will be parsed to Rails::Generator::GeneratedAttribute, this class encapsulate you key-value pair.

for the example above.
name attribute will be “hello”
reset of attribute will create one GeneratedAttribute instance whose name is attr1, type is value1.
You will think it is weird, yes. GeneratedAttribute is actually used for specify database column name and column type.

According to your reqirement, you can choose basic generator or named generator.

Keep DRY and using generator save your time.
rails generator.

This post I’ll show you another type of generator Named Geneerator

What’s the different between basic generator and named generator?

Commonly it used by this kind of generate script/generate generator_name hello attr1:value1

  1. named generator will get first argument you passed in as name attribute, and what’s more it convert name to 3 types of string plural_name,singular_name,table_name
  2. For the reset of attributes will be parsed to Rails::Generator::GeneratedAttribute, this class encapsulate you key-value pair.

for the example above.
name attribute will be “hello”
reset of attribute will create one GeneratedAttribute instance whose name is attr1, type is value1.
You will think it is weird, yes. GeneratedAttribute is actually used for specify database column name and column type.

The missing guide of rails 2 generator part 1

Posted by AllenWei | Posted in RubyOnRails | Posted on 18-02-2010-05-2008

View Comments

When I try to find a guide about how to write rails generator, I can’t find a good one. So I decide wrote one.
Though Rails 3 will come, but I think people will keep using rails 2 for a long period.

Before we start you need know what is generator, rails provide many generator for us. You can type script/generate in your RAILS_ROOT.
You will find there is rails builtin: controller, helper, integration_test, mailer, metal, migration, model, observer, performance_test, plugin, resource, scaffold, session_migration
I think the must familiar with some of these.

Write your own generator is very simple, let me show you.

Assuming we will create a hello generator

1. create folder lib/generators/hello
2. create a ruby file lib/generators/hello/hello_generator.rb

class HelloGenerator < Rails::Generator::Base
  def manifest # this method is default entrance of generator
    puts "hello"
  end
end

3.run script/generate hello, we print “hello”.

It is not enough, we need other function, like create folder, create file according to some template, copy file etc.
Rails is powerful. It support some basic command. I’ll show you one by one.

1. create folder, copy file

class HelloGenerator < Rails::Generator::Base
  def manifest # this method is default entrance of generator
    record do |m| #Convenience method for generator subclasses to record a manifest.
      m.directory File.join("app","view","hello")
      m.file "relative_source","relative_destination"
    end
  end
end

2. create file according to template

class HelloGenerator < Rails::Generator::Base
  def manifest # this method is default entrance of generator
    record do |m| #Convenience method for generator subclasses to record a manifest.
      m.directory File.join("app","view","hello")
      m.template "hello",File.join("app","view","hello","hello.html.erb")
    end
  end
end

template is locate at your generator folder templates sub folder.

For the example above, we create hello.html.erb according to hello template.
hello template acctually is a erb file. you can put some ruby code there.
for example

<ul>
  <% 3.times do |i| %>
  <li><%= i%> times </li>
  <% end %>
</ul>

After we know that, we do some fancy stuff, we can pass in some argument when we generate file.

Think how we generate controller using rails builtin generator.
script/generate controller controller_name action1 action2

we can do the same think. But how we get the argument in generator?
Assuming we call our generator using script/generate hello china world
we can get argument in generator from attribute args

class HelloGenerator < Rails::Generator::Base
  def manifest # this method is default entrance of generator
    record do |m| #Convenience method for generator subclasses to record a manifest.
      puts args.inspect # ["china","world"]
      m.directory File.join("app","view","hello")
      args.each do |word|
        m.template "hello",File.join("app","view","hello","#{word}.html.erb")
      end
    end
  end
end

3. How we pass variable to template file?

class HelloGenerator < Rails::Generator::Base
  def manifest
    record do |m|
      m.template "hello",File.join("app","view","hello","hello.html.erb"),:assigns => {:var1 => "var1",:var2 => "var2"}
    end
  end
end

OK, this is magic time. call this command script/destroy hello china world
See rails delete the resource we created using generator. Even if we didn’t write any extra code for it.

4. how we know it’s create or destroy, you can get it from options[:command]

class HelloGenerator < Rails::Generator::Base
  def manifest # this method is default entrance of generator
    record do |m| #Convenience method for generator subclasses to record a manifest.
      puts options[:command]
    end
  end
end

More command rails generator support see http://api.rubyonrails.org/classes/Rails/Generator/Commands/Create.html

Next part I will introduce another generator Named Generator.
like how we create scaffold script/generate scaffold user name:string age:integer

Tips – variable in partial defined?

Posted by AllenWei | Posted in RubyOnRails, Tips | Posted on 15-02-2010-05-2008

View Comments

When we use variabel in partial, we will meet constant undefined error. How to avoid?

<% if foo.nil? %>

doesn’t work

assuming variable foo
There are two ways:

  1. local_assigns will get all local variables, using local_assigns[:foo],we can get variable value, If this variable is undefined, it will return nil. Not Error.
  1. defined? method
    Using
      defined? :foo

Don’t override ActiveRecord initialize method

Posted by AllenWei | Posted in RubyOnRails | Posted on 15-02-2010-05-2008

View Comments

Today I wrote an ActiveRecord initialize method like this

  def initialize
    @aa = "aa"
  end

Then this error occurred.

NoMethodError: You have a nil object when you didn’t expect it!
The error occurred while evaluating nil.has_key?

Very confuse.

After I saw source of ActiveRecord, I realized I override ActiveRecord default initialize method by mistake.

If you really want to do this. There two ways:

  def initialize(params = nil)
    super
    # do something else
  end

More graceful

  def after_initialize
    @aa = "aa"
  end

Tips – Using symbol in ActiveRecord find

Posted by AllenWei | Posted in RubyOnRails, Tips | Posted on 15-02-2010-05-2008

View Comments

before

Account.find(:all, :conditions => ['name LIKE ? AND updated_at < ?', "aname", 3.days.ago])

After

Account.find(:all, :conditions => ['name LIKE :name AND updated_at < :date', {:name => "aname", :date => 3.days.ago}])

Rotate your log file

Posted by AllenWei | Posted in RubyOnRails | Posted on 15-02-2010-05-2008

View Comments

Configuring

config file locate at /etc/logrotate.conf

Sample:

   # Rotate Rails application logs
   /path/to/your/rails/applicaton/log/*.log {
     daily
     missingok
     rotate 7
     compress
     delaycompress
     notifempty
     copytruncate
   }
  • /path/to/your/rails/applicaton/log/*.log - Use the full path to the log directory of your Rails application (symbolic links are acceptable too). “*.log” will rotate any file in the log directory with .log at the end. If you only want to rotate certain log files you can be more specific.
  • daily - Rotates the log files every day. You could specify weekly or monthly instead.
  • missingok - Don’t issue an error message if log files are missing.
  • rotate 7 - The maximum number of log files to keep. Once you have more than this number, the oldest file will be deleted. I set it to keep seven days worth but feel free to change this number.
  • compress - Compress old versions of log files to save space (uses gzip by default).
  • delaycompress - Delays the compression until the next log rotation. It’s a minor point and probably not strictly necessary, but it makes sure that the log file is truly no longer active before compressing it.
  • notifempty - If the log file is empty, there’s no need to rotate it. You can remove this option if you want to rotate even blank log files; just keep in mind that you may erase a log file that has lots of information to make room for your blank log file.
  • copytruncate - Makes a backup copy of the current log and then clears the log file for continued writing. The alternative is to use create which will perform the rotation by renaming the current file and then creating a new log file with the same name as the old file. I strongly recommend that you use copytruncate unless you know that you need create. The reason why is that Rails, FastCGI, Mongrel, etc. may still keep pointing to the old log file even though its name has changed and they may require restarting to locate the new log file. copytruncate avoids this by keeping the same file as the active file.

If you have more than one Rails application, you can repeat this code to rotate them all one-after-another. There other options you can specify, man logrotate will show you them all. I haven’t used them but the options to mail log files on creation or deletion look interesting. It is also possible to have rotate the logs once they get to a certain size instead of at a certain time.

Using logrotate

To use the log rotation you just configured, you have two choices.

  1. Wait for the next day (or whatever time period you specified). If you configured it correctly, rotation should occur automatically and without further commands.
  2. Run it immediately by typing /usr/sbin/logrotate -f /etc/logrotate.conf on the command line. (The -f is for “force” it to run now.)

That’s all there is to it! Now your log files won’t fill up to an unmanagable size yet you’ll still be able to go back and track any recent errors.

By default, logrotate will add cron task to /etc/cron.daily/logrotate. So you don’t need to worry how to add cron task.

Ads Plugin created by Jake Ruston's Wordpress Plugins - Powered by and football database.