Monday, December 21, 2009

drop down list/collection selection

I have a simple application just like blog tutorial in the book 'Agile Web Development with Rails', it has two models:
class Log < ActiveRecord::Base
belongs_to :product
end

class Product < ActiveRecord::Base
has_many :logs
end
Product has a part_number_id column which Log reference to. Log was created using scaffold while Product was created using script/generate model.

on the new.html.erb and edit.html.erb files for logs, I need to show all available products in a drop down list so user can choose the product and edit log for it. collection_selection is the one to do this.
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})

in new.html.erb, it's easier,
here:
object: is the log model
method: is the log model's attribute: part_number_id
collection: log's part_number_id is choose from Product model
value_method: the value displayed in select & option tag is Product's id
text_method: the text valude displayed in select & option tag is Product's part number
options{:include_blank => 'Please Select'}: when no option is available, display 'Please select' in the select & option tag.

in edit.html.erb, not only do i need to show all available products in dropdown list, also I need to select the part number of that specified log:
in the options, we added one more, :selected => @selected_log, the variable @selected_log was defined in controller/logs_controller.rb
# GET /logs/1/edit
  def edit
    @log = Log.find(params[:id])
    @selected_log = Product.find(@log.part_number_id).id
  end
it tells that the selected option is the one defined ass @selected_log.

Friday, December 18, 2009

checkbox

the model Log has a attribute :status which can be either true(valid) or false (invalid).

the view(edit.html.erb) has a form to show this model, want to use a checkbox to allow user to invalidate the log:
to populate the log's status to the check box:
if log's status is valid, the check box is not checked;
if log's status is invalid, the check box is checked;

to populate the check box's value back to log's status:
if user check the check box, the log's status will be set to false(invalid)
once the check box is checked, user is not allowed to uncheck it.

To Populate from Model to View
The tricky thing here is, the status of the check box is opposite to the log's status, so tried the following ways:
<%= f.label 'Invalide?' %><%= f.check_box !(:status)%>
or 
<%= f.label 'Invalide?' %><%= f.check_box (:status ? 0:1)%>
those wont' work, it complained either 'undefined method 'false' or undefined 0.

read the API again and googled around (kudos to rob-twf's reply at ruby on rails forum), here is the solution:
<%= f.label 'Invalide?' %><%= f.check_box :status, {:checked => !f.object.status} %>

follow the API:
check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") 
object_name: here is our Log model,
method: here is our :status attribute, it has nothing to do with the checkbox's status(checked or not), that's what confused me in the first place
options: html options, here is the place to specify the checkbox's status, checked or not
checked_value & unchecked_value: can safely ignore them in this case.

so in order to set the checkbox checked, we defined the condition in options as:
{:checked => :status ? 0:1}
if log's status is true, uncheck the checkbox, otherwise, check it.

To Populate from View to Model
after the modification from above, we can populate the log.status value correctly to the view(edit.html.erb). then we checked the checkbox to invalidate the log and click Update button, it shows 'Log was successfully updated', however if we go to the database we can see the status is still valid(1). what is wrong?

go to the script/server screen, we found the following statements for the Update click:
Processing LogsController#update (for 127.0.0.1 at 2009-12-18 13:28:43) [PUT]
  Parameters: {"commit"=>"Update", "authenticity_token"=>"dQ3IIa6mI0IrJORrayVQjQa6RHn95AqfVvDahBglGMc=", 
"log"=>{"serial_number"=>"L-000099", "log"=>"Two zipper teeth are missing", "part_number_id"=>"4", 
"status"=>"1", "user"=>"Tom"}, "id"=>"3"}
  Log Columns (1.2ms)   SHOW FIELDS FROM `logs`
  Log Load (0.1ms)   SELECT * FROM `logs` WHERE (`logs`.`id` = 3) 
  SQL (0.1ms)   BEGIN
  SQL (0.1ms)   COMMIT
Redirected to http://localhost:3000/logs/3
Completed in 16ms (DB: 2) | 302 Found [http://localhost/logs/3]
  SQL (0.1ms)   SET NAMES 'utf8'
  SQL (0.1ms)   SET SQL_AUTO_IS_NULL=0
see there is no SQL statements between the BEGIN and COMMIT, the reason is nothing is changed for that log record, so no update to it.

How could that be possible? I just checked the check box to invalidate the log's status, the 'status' should be set to 0. well, go back to read the API further:
check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0") 
By default, if the the check box is checked, it's set to 1, otherwise, set to 0. that's the opposite to what I need here. so go back to edit.html.erb and update the code again:
<%= f.label 'Invalide?' %>
<%= f.check_box :status, {:checked => :status ? 0:1}, checked_value = "0", unchecked_value = "1" %>
now it's happy. without anymore change to the code, it can update the Log correctly.

Wednesday, December 16, 2009

ubuntu emacs php mode

to add PHP syntax highlighting to emacs on ubuntu, install php-mode:
sudo apt-get install php-mode

Tuesday, December 15, 2009

symfony: doctrine couldn't locate driver named mysql

followed the symfony's tutorial at chapter 3, when performed the command: php symfony doctrine:insert-sql, it complained:
doctrine created tables successfully
Couldn't locate driver named mysql

go check php.ini file, pdo_mysql was enabled:  extension=pdo_mysql.so
but when go into folder /etc/php5/conf.d/, only found: pdo.ini, xsl.ini and zend-framework.ini, so maybe pdo_mysql extension was actually not installed?

try to install pdo_mysql extension again:
sudo pecl install pdo_mysql
Ignoring installed package pecl/pdo_mysql
Nothing to install
uninstalled and reinstalled pecl/pdo_mysql wont' help.

searched around and found the solution here.
Odds are that your php.ini file for your CLI (often different from the apache php.ini) 
doesnt have pdo_mysql enabled. Enable it :)  

edit /etc/php5/cli and add the following to the end:
extension=pdo.so
extension=pdo_mysql.so
extension=apc.so
restarted apache and it works!

Saturday, December 12, 2009

install symfone on ubuntu

Try to install symfony on ubuntu:

Follow the get-started tutorial on symfony's website at:http://www.symfony-project.org/getting-started/1_4/en/02-Prerequisites,

run check_configuration.php in the web browser: http://localhost/check_configuration.php and it threw the following result:
********************************
*                              *
*  symfony requirements check  *
*                              *
********************************

php.ini used by PHP: /etc/php5/apache2/php.ini


** Mandatory requirements **

  OK        PHP version is at least 5.2.4 (5.2.6-3ubuntu4.2)

** Optional checks **

  OK        PDO is installed
[[WARNING]] PDO has some drivers installed: : FAILED
            *** Install PDO drivers (mandatory for Propel and Doctrine) ***
  OK        PHP-XML module is installed
[[WARNING]] XSL module is installed: FAILED
            *** Install the XSL module (recommended for Propel) ***
  OK        The token_get_all() function is available
  OK        The mb_strlen() function is available
  OK        The iconv() function is available
  OK        The utf8_decode() is available
[[WARNING]] A PHP accelerator is installed: FAILED
            *** Install a PHP accelerator like APC (highly recommended) ***
  OK        php.ini has short_open_tag set to off
  OK        php.ini has magic_quotes_gpc set to off
  OK        php.ini has register_globals set to off
  OK        php.ini has session.auto_start set to off
  OK        PHP version is not 5.2.9
To fix the first warning, install PDO package for PHP 5 on ubuntu:
sudo apt-get install libmysqlclient15-dev
sudo pecl install pdo

then got the following message:
downloading PDO-1.0.3.tgz ...
Starting to download PDO-1.0.3.tgz (52,613 bytes)
.............done: 52,613 bytes
12 source files, building
running: phpize
sh: phpize: not found
ERROR: `phpize' failed
googled around and found out that need to install php5-dev version, so here we go:
sudo apt-get install php5-dev
sudo pecl install pdo
at the end of the installation, it displayed:
Build process completed successfully
Installing '/usr/include/php/ext/pdo/php_pdo.h'
Installing '/usr/include/php/ext/pdo/php_pdo_driver.h'
Installing '/usr/lib/php5/20060613/pdo.so'
install ok: channel://pecl.php.net/PDO-1.0.3
configuration option "php_ini" is not set to php.ini location
You should add "extension=pdo.so" to php.ini
sudo pecl install pdo_mysql
at the end of installation, it displayed:
Build process completed successfully
Installing '/usr/lib/php5/20060613/pdo_mysql.so'
install ok: channel://pecl.php.net/PDO_MYSQL-1.0.2
configuration option "php_ini" is not set to php.ini location
You should add "extension=pdo_mysql.so" to php.ini
edit php.ini at /etc/php5/apache2/ to add the above 2 lines, restart apache: sudo /etc/init.d/apache2 restart
and check the configuration again in the browser, boo! the first warning is gone!  so far so cool :)
sudo apt-get install php5-xsl
sudo /etc/init.d/apache2 force-reload
then rerun check configuration in browser, yeah, second warning is gone!!!!

to fix the third warning, run:
sudo pecl install apc
and edit php.ini to add 'extension= apc.so', then restart apache2. check the configuration in browser, hola, it's all gone, all the warnings!!!

now can go ahead to have fun with symfony!

Thursday, November 12, 2009

Ext-GWT: The Mail application

Tools:
  • eclipse 3.5 galileo
  • gwt plugin for eclipse, v1.7.1, see installation instruction here
  • download Ext GWT (including Mail application) source code from here, choose 'Ext GWT 2.0.1 SDK' to download all source code and documentation, unzip it, the folder named 'gxt-2.0.1'
Steps:
1.  from eclipse, File->New->Web Application Project
     Project name: Mail
     Package: com.extjs.gxt.samples.mail
     click 'Finish' button.

2. copy the downloaded Mail application source code into the project folder created from step 1, and remove default files created by gwt plugin.

3. copy the resource folder under gxt-2.0.1 to eclipse's Mail project, and rename it to gxt:
    Mail -> war -> gxt

4. created lib folder in Mail project, and copy gxt.jar from gxt-2.0.1 to Mail/lib

5. in eclipse, right click Mail project, select Properties -> Java Build Path -> Libraries tab -> click 'Add External JARs' button -> in 'Edit JAR' window, select Mail -> lib->gxt.jar, then click 'OK' button.

6.   from eclipse, File->New->Web Application Project
     Project name: Resources
     Package: com.extjs.gxt.samples.resources
     click 'Finish' button.

7.  copy the downloaded Resources application source code into the project Resources folder created from step 6, and remove other files created by gwt plugin.

8.  created lib folder in Resources project, and copy gxt.jar from gxt-2.0.1 to Resources/lib

9.  in eclipse, right click Resources project, select Properties -> Java Build Path -> Libraries tab -> click 'Add External JARs' button -> in 'Edit JAR' window, select Resources-> lib->gxt.jar, then click 'OK' button.

10. in eclipse,  right click Mail project, select Properties -> Java Build Path -> Projects tab -> click 'Add' button -> in 'Required Project Selection' window, select 'Resources' project, click 'OK' button.

11. remove the Mail/war/Mail.html file, go to extjs's Mail demo site, right click mouse -> view page source, from the popup window, copy the file and save it to eclipse's Mail project as Mail -> war -> Mail.html.

12. remove the Mail/war/Mail.css file, go to extjs's Mail demo site, right click mouse -> view page source, from the popup window, you see the mail.html file which we just save to our project,  read the first a few line:

<html>
<head>
<title>Ext GWT 2.0.1 Mail Demotitle>
<link rel="stylesheet" type="text/css" href="gxt/css/gxt-all.css" />
<link rel="stylesheet" type="text/css" href="samples/css/resources.css" />
<link rel="stylesheet" type="text/css" href="samples/css/mail.css" />
<style>
..
click the third hyperlink to mail.css file, it will open up in the same popup window, copy the file and save it to Mail/war/Mail.css

13, continue from step 12, click the second hyperlink to resources.css,it will open up in the same popup window, copy the file and save it to Mail/war/resources.css

14. open up Mail/war/Mail.html in eclipse, change the second and third hyperlinks  to the following:

<link rel="stylesheet" type="text/css" href="resources.css" />
<link rel="stylesheet" type="text/css" href="mail.css" />

15. save the project, click Mail, click the 'run' button, it will run the Mail demo application, however, still have problem with mailservice, but at least it show up in eclipse now....more to come later.

Thursday, November 5, 2009

install ZendFramework on ubuntu

1. download and unzip the latest version of ZendFramework to /home/dan/
2. add the zend framework's library to PHP's include path:
    $cd /etc/php5/apache2
    $sudo emacs php.ini
    find the include_path in the php.ini file and edit it:
    include_path = "/home/dan/ZendFramework/library:.:/usr/share/php"
3. restart apache2: $sudo /etc/init.d/apache2 restart
4. create project:
    $zf.sh create project quickstart

Issue:
1. make sure the ZendFramework's library folder is not empty.

2. if install ZendFramework by: sudo apt-get zend-framework
    remove it by: sudo apt-get remove zend-framework
    it might tell you:
    The following packages were automatically installed and are no longer required:
    libzend-framework-php linux-headers-2.6.28-11-generic linux-headers-2.6.28-11
    Use 'apt-get autoremove' to remove them.
    then run: sudo apt-get autoremove