1. Select your Project
2. Edit config\database.yml
development:
database: SourceDatabaseName
3. Delete schema.db
4. Right-click and select Rake\db\schema\load which basically the same as typing into the Rails Shell
5. Edit config\database.yml
development:
database: ProjectDatabaseName
Nb. Assume that you had already create an empty database for your project
6. rake db:schema:load
That's it, when you check your project database, it is already populated with the Source Schema.
Chee Chong Hwa aka CCH, a Malaysian Chief Software Architect blogs on his experiences with Ruby on Rail running on Win2003 Server+Apache 2.26 environment since 2007. Flirted briefly with Ubuntu 9.04 in 2009. Since January 2017, now using RubyMine IDE/Notepad++ to work with Ruby 2.26 +Rails 5.01+Apache 2.4.23 + MySQL 5.7.14 on Windows 10 64-bits.
Showing posts with label Advanced Rails. Show all posts
Showing posts with label Advanced Rails. Show all posts
Wednesday, August 19, 2009
Saturday, November 3, 2007
Advanced Rails : Testing a Ruby on Rails Application [Updated 30th August 2009]
Thanks to DHH and his team, Rails guides you to create a well-tested application by actively generating default test cases and setting up scripts and tools to run 3 different kinds of tests namely, unit testing, functional testing and integration testing.
For example, when you use script/generate to create your models and controllers, Rails also generates skeletal test files for you to flesh out with tests for your apps.
1) Unit Testing deals with tests on models.
2) Controllers are tested via Functional Testing
3) Integration Testing focuses on the testing of the interation between controllers
Rails has a number of features that make it easy to test your application. In particular, Rails uses a separate runtime database dedicated to testing and can automatically populate the test database with fresh sample data (that you provide) before each test.
This is how you execute the tests :-
a) Test all units and functionals
rake test
b) Run tests for functionals
rake test:functionals
c) Run tests for integration
rake test:integration
d) Run tests for units
rake test:units
Testing within Aptana RadRails
1) Select the Rails Project that is to be tested
2) Click the Tests Icon on the ToolBar Nb. Y0u have a choice to select All Tests, Unit Tests, Functional Tests and Integration Tests
3) If you select Unit Tests, you should see a dialog window showing progress with an option to run in the background.

4) On competion of the test, you should see the following result :-

Available assertions for rake test:units
assert_kind_of Class, @var # same class
assert @var # not nil
assert_equal 1, @p.id # equality
@product.destroy
assert_raise(ActiveRecord::RecordNotFound) { Customer.find( @customer.id ) }
Available assertions for rake test:functional
a) Requests
get :action # a get request of the specificed action
get :action, :id => 1,
{ session_hash }, # optional session variables
{ flash_hash } # optional messages in the flash
post :action, :foo => { :value1 => 'abc', :value2 => '123' },
{ :user_id => 17 },
{ :message => 'success' }
get, post, put, delete, head
assert_response :success
# possible parameters are:
# :success
# :redirect
# :missing
# :error
b) Redirects
assert_redirected_to :action => :other_action
assert_redirected_to :controller => 'foo', :action => 'bar'
assert_redirected_to http://crm4web.com.my/
c) Rendered with Template
assert_template "post/index"
d) Variable Assignments
assert_nil assigns(:some_variable)
assert_not_nil assigns(:some_variable)
assert_equal 11, assigns(:posts).size
e) Rendering of Specific Tags
assert_tag :tag => 'body'
assert_tag :content => 'Rails Plugins'
assert_tag :tag => 'div', :attributes => { :class => 'index_list' }
assert_tag :tag => 'head', :parent => { :tag => 'body' }
assert_tag :tag => 'html', :child => { :tag => 'head' }
assert_tag :tag => 'body', :descendant => { :tag => 'div' }
assert_tag :tag => 'ul',
:children => { :count => 1..3,
:only => { :tag => 'li' } }
More to come...
For example, when you use script/generate to create your models and controllers, Rails also generates skeletal test files for you to flesh out with tests for your apps.
1) Unit Testing deals with tests on models.
2) Controllers are tested via Functional Testing
3) Integration Testing focuses on the testing of the interation between controllers
Rails has a number of features that make it easy to test your application. In particular, Rails uses a separate runtime database dedicated to testing and can automatically populate the test database with fresh sample data (that you provide) before each test.
This is how you execute the tests :-
a) Test all units and functionals
rake test
b) Run tests for functionals
rake test:functionals
c) Run tests for integration
rake test:integration
d) Run tests for units
rake test:units
Testing within Aptana RadRails
1) Select the Rails Project that is to be tested
2) Click the Tests Icon on the ToolBar Nb. Y0u have a choice to select All Tests, Unit Tests, Functional Tests and Integration Tests
3) If you select Unit Tests, you should see a dialog window showing progress with an option to run in the background.
4) On competion of the test, you should see the following result :-
Available assertions for rake test:units
assert_kind_of Class, @var # same class
assert @var # not nil
assert_equal 1, @p.id # equality
@product.destroy
assert_raise(ActiveRecord::RecordNotFound) { Customer.find( @customer.id ) }
Available assertions for rake test:functional
a) Requests
get :action # a get request of the specificed action
get :action, :id => 1,
{ session_hash }, # optional session variables
{ flash_hash } # optional messages in the flash
post :action, :foo => { :value1 => 'abc', :value2 => '123' },
{ :user_id => 17 },
{ :message => 'success' }
get, post, put, delete, head
assert_response :success
# possible parameters are:
# :success
# :redirect
# :missing
# :error
b) Redirects
assert_redirected_to :action => :other_action
assert_redirected_to :controller => 'foo', :action => 'bar'
assert_redirected_to http://crm4web.com.my/
c) Rendered with Template
assert_template "post/index"
d) Variable Assignments
assert_nil assigns(:some_variable)
assert_not_nil assigns(:some_variable)
assert_equal 11, assigns(:posts).size
e) Rendering of Specific Tags
assert_tag :tag => 'body'
assert_tag :content => 'Rails Plugins'
assert_tag :tag => 'div', :attributes => { :class => 'index_list' }
assert_tag :tag => 'head', :parent => { :tag => 'body' }
assert_tag :tag => 'html', :child => { :tag => 'head' }
assert_tag :tag => 'body', :descendant => { :tag => 'div' }
assert_tag :tag => 'ul',
:children => { :count => 1..3,
:only => { :tag => 'li' } }
More to come...
Sunday, October 28, 2007
Advanced Rails : Why you should not use Global Variables ! [Updated 12th Sept 2009]
What are global variables in Ruby ?
A global variable has a name beginning with $. It can be referred to from anywhere in a program. Before initialization, a global variable has the special value nil.
Global variables should be used sparingly. They are dangerous because they can be written to from anywhere. Overuse of globals can make isolating bugs difficult; it also tends to indicate that the design of a program has not been carefully thought out. Whenever you do find it necessary to use a global variable, be sure to give it a descriptive name that is unlikely to be inadvertently used for something else later (calling it something like $foo as above is probably a bad idea).
When a global variable has been rigged to work as a trigger to invoke a procedure whenever changed, we sometimes call it an active variable. For instance, it is useful for keeping a GUI display up to date.
There is a collection of special variables whose names consist of a dollar sign ($) followed by a single character. For example, $$ contains the process id of the ruby interpreter, and is read-only. Here are the major system variables and their meanings (see the ruby reference manual for details):
$! latest error message
$@ location of error
$_ string last read by gets
$. line number last read by interpreter
$& string last matched by regexp
$~ the last regexp match, as an array of subexpressions
$n the nth subexpression in the last match (same as $~[n])
$= case-insensitivity flag
$/ input record separator
$\ output record separator
$0 the name of the ruby script file
$* the command line arguments
$$ interpreter's process ID
$? exit status of last executed child process
In the above, $_ and $~ have local scope. Their names suggest they should be global, but they are much more useful this way, and there are historical reasons for using these names.
Why you should not not use Global Variables
Let us assume that on login (say using Acts As Authenticated), you may be tempted to initialise say $is_admin = current_user.isadmin and then use $is_admin to control access to modules or whatever. This will work very nicely in development mode or even production mode under say Apache 2.x + 1 mongrel process.
However, once you use Apache 2.2x + a pack of mongrel processes, your security measure will fail miserably ! Why ?
Prior to using Apache+a pack of mongrels, I was succesfully using a home-made role-based authentication in conjunction with AAA.
What I did basically was to add roles in users (AAA table) via adding fields (such as is_admin, is_marketing, is_finance etc). The result is that a user can can have one or many roles.
With this concept, I could control access to modules using layouts and within each controller or model I can control access to specific actions.
1. Control access to specific actions via controller.
EXAMPLE in customers_controller.rb
layout 'customers'
active_scaffold :customer do config
if User.current_user.is_admin
config.nested.add_link("Receivables", [:receivables])
end
2. Control access to specific actions via model
has_many :receivables
def authorized_for_update?
current_user.is_finance
end
def authorized_for_destroy?
current_user.is_admin
end
Using 1-3 works perfectly on Apache+1 mongrel on a Windows 2003. But once I activate Apache + 2 or mongrels, the whole security system got thrashed !
Response from Jan (Mongrel FAQ)
Globals are not shared across different instance of mongrel. To have a global appear in all instances you need some form of permanent storage (filesystem or database). If it doesn't need to change over the lifetime of the program you can pass in the global at startup in an environment variable.
You would not want to use a global in this case, since it needs to change after start up and the other mogrels would not be aware of the change. Use permanent storage. File system, database, or perhaps even a cookie
Response from Luis (author of mongrel windows service)
As Jan pointed, global variables aren't shared across processes.
You need rely your authorization schema in something else instead a global variable, since 2 users could hit the same mongrel instance and both get great as admin.
You need to investigate further about authorization schemas and how session is handled (and could be used for your purpose).
First you need to move your session storage to ActiveRecord or cookie based (in case of 1.2.5 or edge). Then I suggest you take a look at the following plugins for Authentication:
RESTful Authentication:
http://railsify.com/plugins/3-restful-authentication
Acts as Authenticated: http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated
Later you will need some role management (to handle is_admin?) Take a look at the suggestion and the "Elsewhere" part from the Acts as Authenticated stikipad page.
My solution was to use the role_requirement plugin by Tim Harper.
This link is also relevant to our discussion here.
A global variable has a name beginning with $. It can be referred to from anywhere in a program. Before initialization, a global variable has the special value nil.
Global variables should be used sparingly. They are dangerous because they can be written to from anywhere. Overuse of globals can make isolating bugs difficult; it also tends to indicate that the design of a program has not been carefully thought out. Whenever you do find it necessary to use a global variable, be sure to give it a descriptive name that is unlikely to be inadvertently used for something else later (calling it something like $foo as above is probably a bad idea).
When a global variable has been rigged to work as a trigger to invoke a procedure whenever changed, we sometimes call it an active variable. For instance, it is useful for keeping a GUI display up to date.
There is a collection of special variables whose names consist of a dollar sign ($) followed by a single character. For example, $$ contains the process id of the ruby interpreter, and is read-only. Here are the major system variables and their meanings (see the ruby reference manual for details):
$! latest error message
$@ location of error
$_ string last read by gets
$. line number last read by interpreter
$& string last matched by regexp
$~ the last regexp match, as an array of subexpressions
$n the nth subexpression in the last match (same as $~[n])
$= case-insensitivity flag
$/ input record separator
$\ output record separator
$0 the name of the ruby script file
$* the command line arguments
$$ interpreter's process ID
$? exit status of last executed child process
In the above, $_ and $~ have local scope. Their names suggest they should be global, but they are much more useful this way, and there are historical reasons for using these names.
Why you should not not use Global Variables
Let us assume that on login (say using Acts As Authenticated), you may be tempted to initialise say $is_admin = current_user.isadmin and then use $is_admin to control access to modules or whatever. This will work very nicely in development mode or even production mode under say Apache 2.x + 1 mongrel process.
However, once you use Apache 2.2x + a pack of mongrel processes, your security measure will fail miserably ! Why ?
Prior to using Apache+a pack of mongrels, I was succesfully using a home-made role-based authentication in conjunction with AAA.
What I did basically was to add roles in users (AAA table) via adding fields (such as is_admin, is_marketing, is_finance etc). The result is that a user can can have one or many roles.
With this concept, I could control access to modules using layouts and within each controller or model I can control access to specific actions.
1. Control access to specific actions via controller.
EXAMPLE in customers_controller.rb
layout 'customers'
active_scaffold :customer do config
if User.current_user.is_admin
config.nested.add_link("Receivables", [:receivables])
end
2. Control access to specific actions via model
has_many :receivables
def authorized_for_update?
current_user.is_finance
end
def authorized_for_destroy?
current_user.is_admin
end
Using 1-3 works perfectly on Apache+1 mongrel on a Windows 2003. But once I activate Apache + 2 or mongrels, the whole security system got thrashed !
Response from Jan (Mongrel FAQ)
Globals are not shared across different instance of mongrel. To have a global appear in all instances you need some form of permanent storage (filesystem or database). If it doesn't need to change over the lifetime of the program you can pass in the global at startup in an environment variable.
You would not want to use a global in this case, since it needs to change after start up and the other mogrels would not be aware of the change. Use permanent storage. File system, database, or perhaps even a cookie
Response from Luis (author of mongrel windows service)
As Jan pointed, global variables aren't shared across processes.
You need rely your authorization schema in something else instead a global variable, since 2 users could hit the same mongrel instance and both get great as admin.
You need to investigate further about authorization schemas and how session is handled (and could be used for your purpose).
First you need to move your session storage to ActiveRecord or cookie based (in case of 1.2.5 or edge). Then I suggest you take a look at the following plugins for Authentication:
RESTful Authentication:
http://railsify.com/plugins/3-restful-authentication
Acts as Authenticated: http://technoweenie.stikipad.com/plugins/show/Acts+as+Authenticated
Later you will need some role management (to handle is_admin?) Take a look at the suggestion and the "Elsewhere" part from the Acts as Authenticated stikipad page.
My solution was to use the role_requirement plugin by Tim Harper.
This link is also relevant to our discussion here.
Thursday, October 11, 2007
Advanced Rails : Moving an Existing Database to a Rails Application
Assuming that you have an existing application that you wish to rewrite in Rails, how would you prepare your database schema so that you can take advantage of the magick of db:migrate ?
Well, I had to do exactly that when I decided to rewrite an existing 200+tables CRM solution into e-CRM, a Rails application. This is what I did :-
a) Pluralize all the table names
Tip: One legacy table was named customer. To pluralize it to customers whilst retaing the data, I use CREATE TABLE customers SELECT * FROM customer for MySQL
b) Add an id field (auto-increment, integer) to every table
c) Add created_at, updated_at in every table to take advantage of Rails automatic updating of these fields without a single line of code
d) Added another magic column ie lock_version (must default to 0) to invoke optimistic locking
e) To support a belongs_to relationship, add belongs_to_tablename
f) Create a schema_info table with just 1 field ie Version, Integer and add a single record with the value=1
g) Use Rake db:schema:dump to create a schema.rb based on the underlying database schema . See following snapshot of Radrails in action
h) Create an empty migration file say 001_migrate2mysql and copy the contents to the Self.Up Method as shown in the Radrails snapshot as follows :-Well, I had to do exactly that when I decided to rewrite an existing 200+tables CRM solution into e-CRM, a Rails application. This is what I did :-
a) Pluralize all the table names
Tip: One legacy table was named customer. To pluralize it to customers whilst retaing the data, I use CREATE TABLE customers SELECT * FROM customer for MySQL
b) Add an id field (auto-increment, integer) to every table
c) Add created_at, updated_at in every table to take advantage of Rails automatic updating of these fields without a single line of code
d) Added another magic column ie lock_version (must default to 0) to invoke optimistic locking
e) To support a belongs_to relationship, add belongs_to_tablename
f) Create a schema_info table with just 1 field ie Version, Integer and add a single record with the value=1
g) Use Rake db:schema:dump to create a schema.rb based on the underlying database schema . See following snapshot of Radrails in action
Updated on 4th November, 2007.
Subscribe to:
Posts (Atom)
Welcome to Rails.. Rails... Rails !
In 1995, I started the popular Clipper...Clipper... Clipper website (no blogs then) which was very popular and linked by virtually every Clipper-related site. When I switched to Windows via Delphi in 1997, I started the Delphi... Delphi... Delphi site. In June 2007, I discovered Ruby on Rails and no prize for guessing what I am gonna name this blog. which I started on 2nd October 2007.
As at 10th June 2010, we have 13,364 unique visitors from more than 84 countries such as Angola, Andorra, Argentina, Australia, Austria, Algeria,Barbados, Bosnia and Herzogovina, Belgium, Brazil, Bulgaria, Bangladesh, Belarus, Bolivia, Chile, Cambodia, Cape Vede, Canada, China, Colombia, Costa Rica, Croatia, Cyprus, Czech Republic, Denmark, Egypt, Estonia, Finland, France, Guadeloupe, Guatemala, Germany, Greece, Hong Kong, Hungary, India, Indonesia, Ireland, Israel, Italy, Japan, Kenya, Korea, Lithuania, Latvia, Malaysia, Mexico, Macao, Netherlands, Nepal, Norway, New Zealand, Oman, Panama, Peru, Poland, Portugal,Paraguay , Philippines, Romania, Russian Federation, Saudi Arabia, Singapore, Spain, Slovakia, Slovenia, Serbia, South Korea, Slovenia, South Africa, Spain, Switzerland, Sri Lanka, Sweden, Taiwan, Thailand, Turkey, United Arab Emirates, Ukraine, USA, UK, Venezuela, Vietnam
CCH
10th June 2010, 19:42
As at 10th June 2010, we have 13,364 unique visitors from more than 84 countries such as Angola, Andorra, Argentina, Australia, Austria, Algeria,Barbados, Bosnia and Herzogovina, Belgium, Brazil, Bulgaria, Bangladesh, Belarus, Bolivia, Chile, Cambodia, Cape Vede, Canada, China, Colombia, Costa Rica, Croatia, Cyprus, Czech Republic, Denmark, Egypt, Estonia, Finland, France, Guadeloupe, Guatemala, Germany, Greece, Hong Kong, Hungary, India, Indonesia, Ireland, Israel, Italy, Japan, Kenya, Korea, Lithuania, Latvia, Malaysia, Mexico, Macao, Netherlands, Nepal, Norway, New Zealand, Oman, Panama, Peru, Poland, Portugal,Paraguay , Philippines, Romania, Russian Federation, Saudi Arabia, Singapore, Spain, Slovakia, Slovenia, Serbia, South Korea, Slovenia, South Africa, Spain, Switzerland, Sri Lanka, Sweden, Taiwan, Thailand, Turkey, United Arab Emirates, Ukraine, USA, UK, Venezuela, Vietnam
CCH
10th June 2010, 19:42