I've put together information about some problems and solutions I've encountered on a blog here:\n\n http://nicholshayes.myzen.co.uk/blog/?cat=3\n\nThe blog include descriptions of the usage of TempObject and action_name_is?, and some information on ignoring files in TortoiseSVN.
!!To create an application call cookbook\nCreate the application:\n{{{\nrails cookbook\n}}}\n\nCreate databases in MySQL. For the example, you'd need cookbook_production, cookbook_development, and cookbook_test databases.\n\nCreate a new scaffold with controller Admin and model Recipe (see ScaffoldHelp).\n{{{\nruby script/generate scaffold Recipe Admin\n}}}\nHowever, this requires a table in the database, and the easiest way to do that is to create the model and associated migration! so do this first.\n\nCreate the same without scaffold\n{{{\nruby script/generate controller Admin\nruby script/generate model Recipe\n}}}\n\nCreate migration for Recipe table\n{{{\nruby script/generate migration Recipe\n}}}\nThis generation:\n{{{\nruby script/generate model JobFile\n}}}\ncreates a model file job_file.rb\n
!!Contrack - A contract tracking system\nBuild to replace a couple of spreadsheets, this system will help Moya keep track of which customers have software support contracts and when renewals are due.\n\nThis is my first real RubyOnRails project.\n\nFirst stage was to build basic object models and testing modules.\n\n//16-Mar-06//\nFirst version has been shown to Mandy and Moya, who approve. This version allows entry of contract info, new customers and new users. Contract object calculates contract end, if in contract and monthly accruals. Basic validation also in place.\n\nNext stage, is to improve validation, bring test plans up to date, and add listing of a customer's contracts when viewing thier information.\n\nAlso this project has raised issue of version control. Yesterday added project to Source safe, but considering using Subversion as better able to deal with Rails tree structure. Installed SubVersion and now using this for version control of project rather than source safe. Updated Alec to this effect.\n\n//17-Mar-06//\nAdd another method to contract that calculates cost of accrued time.\n\nUsed this update to test Subversion system. There is now one repository on Miggins, and two working copies. One on Miggins and one on Flash. Installed and configured MySQL on Flash to work with application so that can run locally for local working copy. System worked fine. I was able to commit changes on Flash, and then update them to the working copy on Miggins.\n\nOnly thing to be aware of is that log and db files are changed on running tests. This could cause conflicts. Found easiest solution was to revert the Flash log and db files back to the previous version on completion of tests. However, if your using the WeBrick http server in the development environment, you'll need to stop this before you can revert all the logs.\n\nHave got function validation working on the contract controller.\n\n//27-Mar-06//\nHave added to functionality of customer controller and model. Moved controller off scaffold so all functions now handled by custom actions. Now lists contracts for each customer and calculates number of contracts, total cost to renew, and total amount outstanding.\n\nCreated renewal action: this is a cut down copy of the edit function, that only presents renewal items, preloads calculated renewal cost in form. Displays breakdown of renewal cost.\n\nAdded XHTML definition to start of layouts. Pages now validate to XHTML.\n\nFunctional test plans for contract controller in place and working.\n\nNeed to add test plans for customer controlled.\n\nMeeting with Moya, Manady and John to discuss project. Development on hold awaiting decision of meeting.\n\n//28-Mar-06//\nTried to fix anomoly caused by way Ruby calculates months. Basically if you say thisday is 3 months after today, what you actually say is thisday = today + (3 * 30). This means that tests can fail around month end. The more I tried to fix the problem, the more complicated the code became. In the end decided to leave anomoly, and add notes to tests stating possible problem.
You can determine the current controller name from within a view using self.controller.controller_name. Likewise the view name is given by self.controller.action_name. Therefore you can do this:\n{{{\n<% if self.controller.controller_name == 'expense_claims' -%>\n <p>This code is displayed if the controller is 'expense_claims' (ExpenseClaimsController).</p>\n<% end -%>\n<% if self.controller.action_name == 'new' -%>\n <p>And this code will be displayed in the view or action is 'new'.</p>\n<% end -%>\n}}}
RubyOnRails
If you have dynamic content of which content is controlled by an if statement, you can be left empty HTML tags that fail strict validation of the output. For example:\n{{{\n<p><%= @output_text if @some_test -%></p>\n}}}\nWill generate\n{{{\n<p></p>\n}}}\nWhen @some_test is false.\n\nIn the past, I have 'fixed' this problem by (originally) putting the if statement outside the HTML tags:\n{{{\n<% if @some_test %>\n<p><%= @output_text --%></p>\n<% end %>\n}}}\nor (lately) inserting the tags within the Ruby code that is controlled by the if statement:\n{{{\n<%= "<p>#{@output_text}</p>" if @some_test %>\n}}}\nHowever, TheRailsWay gives a much neater solution using contect_tag:\n{{{\n<%= content_tag('p', @output_text) if @some_test %>\n}}}
http://www.fastcgi.com/\n\nA plug in to Apache. It greatly improves the performance of CGI processes. For example, with Ruby on Rails, it uses small footprint Ruby instances rather than letting Apache open new instances with a ruby apache module.
!find joins sort MS SQL and square brackets\n\nDon't use square brackets in your custom SQL //find// options.\n\nIf you use square brackets in your customer //find// options, you can come a cropper if you use :limit and/or :offset (for example, when paginating).\n\nFor example:\n!!!This doesn't work\n{{{\nclass Opportunity << Base\n def self.find_test\n find(:all,\n :select => "\n[o].*,\n [c].[Comp_Name],\n [p].[Pers_Salutation] AS person_salutation,\n [p].[Pers_FirstName] AS person_first_name,\n [p].[Pers_LastName] AS person_last_name,\n [u].[User_FirstName] AS user_first_name,\n [u].[User_LastName] AS user_last_name\n",\n :joins => "\nAS [o]\nLEFT JOIN [Company] AS [c]\n ON [o].[Oppo_PrimaryCompanyId] = [c].[Comp_CompanyId]\nLEFT JOIN [Person] AS [p]\n ON [o].[Oppo_PrimaryPersonId] = [p].[Pers_PersonId]\nLEFT JOIN [Users] AS [u]\n ON [o].[Oppo_AssignedUserId] = [u].[User_UserId]\n",\n :order => '[c].[comp_name]',\n :limit => 30,\n :offset => 30)\n end\nend\n\nOpportunity.find_test\n}}}\n!!!This does work:\n{{{\nclass Opportunity << Base\n def self.find_test\n find(:all,\n :select => "\no.*,\n c.Comp_Name,\n p.Pers_Salutation AS person_salutation,\n p.Pers_FirstName AS person_first_name,\n p.Pers_LastName AS person_last_name,\n u.User_FirstName AS user_first_name,\n u.User_LastName AS user_last_name\n",\n :joins => "\nAS o\nLEFT JOIN Company AS c\n ON o.Oppo_PrimaryCompanyId = c.Comp_CompanyId\nLEFT JOIN Person AS p\n ON o.Oppo_PrimaryPersonId = p.Pers_PersonId\nLEFT JOIN Users AS u\n ON o.Oppo_AssignedUserId = u.User_UserId\n",\n :order => 'Comp_Name',\n :limit => 30,\n :offset => 30)\n end \nend\n}}}\nActive record tries to escape out the limit and offset text if it detects a square bracket in the code, and this causes the SQL call to fail.\n\nNote also that you have to be careful with the field name used in :order as the limit and offsets are used against the results of an initial SELECT statement. Therefore, the :order field name needs to be consistent across is successive SELECT statement. If you use AS to alias the field you want to order by, use the alias in the :order statement.
The following fires and external script:\n{{{\nrequire 'win32ole'\n@WSHShell = WIN32OLE.new("WScript.Shell")\n@WSHShell.run "lib/file.bat"\n}}}\nNote that this is defined in a Rails application (application.rb for example). The default path is the root of the application. Therefore this code fires a batch file called "file.bat" in the lib file of the current Rails application.
start_form_tag has been depreciated. However, it was just an alias for form_tag, so you should just be able to delete the "start_".\n\nend_form_tag has been depreciated. Replace with "</form>".\nI created this in application helper:\n{{{\ndef end_form_tag\n "</form>"\nend\n}}}\nBut in many places it was better to replace the end_form_tag with:\n{{{\n<% form_tag(arguments) do %>\n ... form elements ...\n<% end %>\n}}}\nUsing form_tag with a do loop puts an end form tag at the "<% end %>" position.
!Rmagick\nhttp://rubyforge.org/projects/rmagick/\nRMagick is an application that allows you to manipulate graphics from the command line or programmatically within code. Ruby can use it to create and edit images.\n!!Install\nDown load the windows binary. At time of writing this was:\nrmagick-1.13.0-IM-6.2.9-0-win32.zip\n\nExtract the contents to a new location and run the executable - at time of writing:\nrmagick-6.2.9-0-Q8-windows-dll.exe\n\nThen install the gem by opening a command prompt in the folder where the gem is located, and running this command:\n{{{\ngem install rmagick --local\n}}}\nThe readmes in the package give more information including installation tests.\n\n!Gruff\nhttp://nubyonrails.com/pages/gruff\nGruff is a package that uses rmagick to generate graphs. Gruff is a Rails extension or plug-in. I'm using it as a plug-in. \n!!Install\nRun this at the root of the application:\n{{{\nruby script/plugin install http://topfunky.net/svn/plugins/gruff\n}}}\nNote that it took a reboot before the system worked properly!\n!!Gruff controller\nYou can create a gruff controller called Reports (if you are using the plug-in version of Gruff) with the following command:\n{{{\nruby script/generate gruff Reports\n}}}\nThis is useful as the controller includes an example line graph.
* Install Ruby using the one click installer. \n* Use the following command at the command prompt to install Rails\n{{{\ngem install rails --include-dependencies\n}}}\n* You're then ready to BuildARailsApp\n* There is also the option to Install mongrel to use instead of WEBrick. MongrelInstall, describes how I installed mongrel on an XP PC. Biggest problem came from having to upgrade the version of Ruby I was using and then messing up the Rails install.
JavaScript is not the same as Java. The languages are quite different and should not be thought of as related.\n\nJavaScript is ''THE'' universal dynamic browser script. VBScript will work browser side, if the user is using Internet Explorer (IE), but is problematic with browsers such as Mozilla and Opera. Javascript is universally accepted (though there are a few variations between the way different browsers work with Javascript that you need to be aware of - alway test in Firefox and IE before publishing a page). \n\nJavaScript is very powerful and you can do some very neat tricks with it (For example have a look at [[this site|http://www.javascript-fx.com/]], and this Wiki document itself for that matter). However, it is harder to debug than VBScript. Without special tools it is unlikely to generate an error report let alone give you an useful error report. However, the Firefox Javascript console gives error messages that will allow successful debugging, and I use this a lot.\n\nLike VBScript, JavaScript is not typed. I try to keep to the same object naming convention as I use in VBScript, but this can get confusing (is it a JavaScript object or a VBScript object), especially as I often load JavaScript arrays with server side data using VBScript. Therefore, I also tend to use a lot of //this// and //my// prefixes (these are used a lot in examples I've read). To overcome this problem, I try to make my JavaScript object names very descriptive, rather than conforming to a standard layout.\n\nJavaScript uses curly brackets to group code. I find it can be difficult to work out which closing curly bracket relates to which group or loop. Therefore, I find indenting the script is essential to keep track of group postition. I try to put the last bracket on the last working level of the block. I think this:\n{{{\nfunction validatethis() {\n bit of code\n }\n}}}\nis easier to track than\n{{{\nfunction validatethis() {\n bit of code\n}\n}}}\n\nHowever, I must admit that some pages use the latter format. The main point is that I endeavour to be consistant within each page.\n\nA major problem I have found with JavaScript is ensuring that an else statement matches the right if statement. For example look at this:\n{{{\nif (x>2) {\n if (y>4) {\n z=5;\n }\n else {\n z=3;\n }\n }\n}}}\nWhich if statement does the else belong to. It should be the inner one, but it is not always clear, and I think the parsing tool sometimes gets it wrong. To avoid problems I try to always put an else statement with every if in a stacked if block as I think this makes it a little clearer. For example:\n{{{\nif (x>2) {\n if (y>4) {\n z=5;\n }else{}\nelse {\n z=3;\n }\n }\n}}}\nhere the addition of an else{} has made it very clear that the z=3 applies when x>2 fails.\n
!System to upload Sage job number report data to intranet\nMandy prints out a list of Job Codes/numbers that she sends around to people. However, Sage can also create a CSV file that contains the data.\n\nI have this week (//30-Mar-06//) created a RubyOnRails application that allows a user to update such a CSV file and use it to populate a MySQL table with the data contained in it. \n\nThe application also allows users to view the list of job codes and search the data.\n\nNow the data is in MySQL it will be available to other application. As this is an important requirement for WhoShe, I have made this the first WhoShe component!\n\n//4-Apr-06//\nThe job code system is now live. This was a useful exercise as it taught me about the Rail production environment (see RubyOnRails notes). Feedback has been good so far.\n\nThe new tool uses the file load process described above to up load data files and then populate a table. The resultant list of Job codes is searchable (by description) or can be broken down in to job code types. Pagination occurs on all lists greater than 50 lines long. The search box uses an AJAX look ahead, to provide uses with an initial list of possible matches. This is the first application of AJAX on the intranet!!!!
RubyOnRails\nRailsNotes\nRoRUpgrade\nRubyNotes\nBuildARailsApp\nRakeMigration\n
If you create a method like this:\n{{{\ndef method_name(args={})\n}}}\nYou can pass arguments in as part of a hash called args. For example,\n{{{\ndef double_something(args={})\n args[:something] = rand(100) unless args[:something]\n return 2 * args[:something]\nend\n\ndouble_something ---> double a random number from 0 to 100\ndouble_something(:something => 3) ---> 6\n}}}\n
MS SQL requires a custom adapter.\n{{{\ngem install activerecord-sqlserver-adapter --source=http://gems.rubyonrails.org\n}}}\nThen get ADO.rb from:\n\nhttp://rubyforge.org/projects/ruby-dbi/\n\nAnd copy the file to \n\ndrive_letter:>\sruby\slib\sruby\ssite_ruby\s1.8\sDBD\sADO\sADO.rb\n\nGet dbi-0.2.2.zip\n\n!!!Installing 2.3.4 on a new Vista PC\nConnections to MSSQL wouldn't work. In the end I deleted \n{{{\nC:\sruby\slib\sruby\sgems\s1.8\sgems\sdbi-0.4.1\n}}}\nAnd then ran\n{{{\ngem install dbi\n}}}\nand this updated the system to dbi-0.4.3 which seemed to fix the problem
RakeMigration is used to manage the process of creating and updating database tables. With migrations it is fairly easy to create fields of the following types:\n{{{\n:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean\n}}}\nBut what if you want a double. A fix was found here:\n\nhttp://jblevins.org/computing/rails/rails-and-mysql-types\n\nBasically you create the field as a :float and set the precision as 53 using :limit. For example:\n{{{\nclass CreateThings < ActiveRecord::Migration\n def self.up\n create_table :things do |t|\n t.float :length, :limit => 53\n t.timestamps\n end\n end\n\n def self.down\n drop_table :things\n end\nend\n}}}
Modules are used to mix in functions into many Classes. For example, if the classes Pig, Muppet, Frog each had a method likes_miss_piggy?, you could define like_miss_piggy? once in a module and then mix it into the three classes.\n!!Module name\nSame naming convention as Class. So in our example, we could call the Module {{{PiggyTest}}}\n!!The file holding the module.\nThe file name for a module called {{{PiggyTest}}} would be piggy_test.rb. The file would look like:\n{{{\nmodule PiggyTest\n\n def likes_miss_piggy?\n .... bit of code that determine's liking of miss piggy ....\n end\n\nend\n}}}\nNot sure where to put the file. Both /components and /lib work.\n!!Using within each Class\nFor a class to have the module mixed in it needs to have an include statement. E.g.:\n{{{\ninclude PiggyTest\n}}}\nSo if the Frog model includes this line, you can do:\n{{{\nkermit = Frog.find(1)\nif kermit.likes_miss_piggy?\n .... do something ....\nend\n}}}
Playing with Mongrel as an alternative web server. Info here:\n\nhttp://mongrel.rubyforge.org/\n\n!!Upgrade Ruby\nHowever, first need to update to at least 1.8.3 of Ruby. (get version from "ruby -v" at command line). Downloading new Ruby installer from:\n\nhttp://rubyforge.org/projects/rubyinstaller/\n\nInstalling this first required me to uninstall the previous Ruby install together with installed Gems. So I also had to reinstall Rails.\n \n!!Initial problem\nI hit an error when trying to start WEBrick stating that there was a problem with the initializes. I think the problem was that I installed Rails with \n{{{\ngem install Rails\n}}}\nrather than\n{{{\ngem install rails\n}}}\nWhen I reinstalled with a lower case r, everything worked fine.\n\n!!Installing Mongrel\nUsed gem to install Mongrel:\n{{{\ngem install mongrel_service\n}}}\nAccepted dependancies (gem_plugin, mongrel 0.3.13.3 (mswin32), win32-service 0.5.0) and chose latest mswin32 versions when prompted.\n\n!!Creating service\nI wanted a Mongral instance of whoshe to run. Installed the service with:\n{{{\nmongrel_rails service::install -N whoshe \s -c c:\sweb\swhoshe -p 4000 -e development\n}}}\nStarted service via Services in Control Panel. Service appears labelled "whoshe". Seems to work a treat. Set service to Automatic, so that it starts on system boot. Application is now on port 4000.\n\nTo remove the service created in the previous command, use:\n{{{\nsc delete whoshe\n}}}\n\n
This is the prefered database used on the intranet. Main database resides on Miggins. This system has replaced Access as the main database type used, but old Access systems have not been transferred to the new system.\n\nAdmin user is root. Uses same password as domain admin. A less privilaged user is used for web app access. This is ASPSystem that uses the password Sh1th34d.\n\nAccess for intranet is provided by Myodbc installed on the server. Odbc and the underlying ADO set a couple of limitations on MySQL:\n* count(*) will not work. The number returned is too big for the odbc connection. You can use cast so that the number is returned as a string: cast(count(*) as char). This works.\n* Recordset.move doesn't work. Instead have to use Recordset.movenext and loop through the number of times you need to move forward.\n\nNote that RubyOnRails has native connection to MySQL and does not access the database via Odbc. The connection settings are defined in \sconfig\sdatabase.yml.\n\n!!Restore database\nTo restore the a database dump (in .sql format) you must do it from the command line:\n{{{\nmysql -h localhost -u root -p < backup_file.sql\n}}}\nYou will be prompted to enter the root password\n\nHowever, see RestoringMySQLdata
If you used paginate in your version 1 app, you'll need to install "will_paginate" in Rails 2 as paginate is no longer a core element in Rails.\n{{{\ngem install will_paginate\n}}}\nThen add "require will_paginate" into config/environment.rb, below the Rails::Initializer.run loop.\n{{{\nRails::Initializer.run do |config|\n ...\nend\n\nrequire 'will_paginate'\n}}}\n\nThen update controllers to use new model method "paginate"\n{{{\n @support_cases = SupportCase.paginate(:page => params[:page],\n :per_page => 30,\n :conditions => [@conditions_text.join(" AND "), @conditions_data].flatten,\n :order => sort_options)\n}}}\n\nIn views where pagination is to appear enter:\n{{{\n<%= will_paginate @support_cases %>\n}}}\nThis seems to pick up url based params well (so GET set params), but not form based params (POST params). For POST params I used a helper method I'd created to extract params from nested params, and this seems to work. So in application_helper.rb I made this method public:\n{{{\n #If in a view or helper method, you pass the params from one page to the next via link options\n #you can get problems if params itself contains hashes. They become concatenated,\n #and links created from the passed on params, don't work.\n #This method generates the options for a link based on the contents of params,\n #and ensures that the contents of sub-hashes don't get concatenated together.\n def get_options_from_params(skip_keys = [])\n output = Hash.new\n skip_keys << "commit"\n params.each do |key, value|\n next if skip_keys.include?(key)\n if params[key].kind_of? Hash\n params[key].each{|sub_key, sub_value| output["#{key}[#{sub_key}]"] = sub_value}\n else\n output[key] = value\n end\n end\n return output\n end\n}}}\nAnd used it like this:\n{{{\n<%= will_paginate @companies, :params => get_options_from_params %>\n}}}\nThe new pagination links are placed in a div element called pagination. Therefore you may need to updated the css to something like this:\n{{{\ndiv.pagination {\n font-size: 0.7em; \n}\n}}}\nThis form catch instances where a non-paginated version of the item array gets passed to the view:\n{{{\n <%= will_paginate @support_cases if @support_cases.methods.include?('total_pages') %>\n}}}\n\nSee UpgradeWillPaginate
!!Programming Ruby: The Pragmatic Programmer's Guide\n''By Dave Thomas, Chad Fowler, and Andy Hunt''\n\nA very good starting point for anyone interested in either Ruby or Rails. The first edition is included in the Windows Ruby installer documentation as ''Ruby Book Help''.
!!!RDoc - Ruby documentation tool\nThis tool creates HTML documents that describe the ruby code within an application. The core Ruby api documentation is an example of RDoc output:\n\nhttp://www.ruby-doc.org/core/\n\nEach object, method and attribute is isolated and listed. Any comments immediately above an item definition, are used in the documentation. So:\n{{{\n# This is a comment about the class\nclass Thing\n\n # This is a comment about the method\n def a_method\n # some code\n end\n\nend\n}}}\nRDoc will generate a page describing the class. At the top will be the class name followed by the first comment "This is a comment about the class". Below this will be a section for each method. The comment "This is a comment about the method" will be associated with the method a_method. The comment "some code" will not appear in the main documentation (other than appearing when you reveal code.\n\nThere are various references on the web as to the syntax to use with RDoc. For example:\n\nhttp://vision-media.ca/resources/ruby/ruby-rdoc-documentation-syntax\n\nAnd also Chapter 16 of the PickaxeBook describes its use.\n\nWhat I didn't find immediately was how to mark up code. In fact it is simple. Just indent it by two more spaces:\n{{{\n# This is come normal documentation text\n# this is code\n}}}\nThe first line will appear as normal, and the second will appear as code (with line feeds preserved).\n\n!!Generating RDoc\nTo create the RDoc documentation in a Ruby project, simply run ''rdoc'' in the root of the application.\n\nIn a Rails project you need to run ''rake doc:app'' in the root of the application.\n\nI found that once you created the documentation, altering one document can mean only that document is listed in the main RDoc page. Simplest way to avoid this is to delete any pre-existing documentation before running RDoc.\n\nThe RDoc documentation is created in a folder called ''doc'' in the application root. The initial main document used to navigate to the others is ''doc/index.html''.
You can open a Rails console with:\n{{{\nruby script/console\n}}}\nTo open a console in production environment, use:\n{{{\nruby script/console production\n}}}\nTo reload the application (so that you can test changes made to models etc. without reloading the whole console) from within a console session use:\n{{{\n#Rails V1\nDispatcher.reset_application!\n\n#Rails V2\nreload!\n}}}\nNote the exclamation mark at the end\n
!The main item types that define the Rail Application. \nAny file with a name that includes Application, provides functionality for the whole application. E.g the application_helper provides code for all views. A helper called item_helper would only provide code for views accessed via the item_controller\n!!Controllers\nControl flow of application. Used to decide which views are available and when, and process data from models for views.\n!!Models\nDefine the main data objects. Much of this is done by default (table fields become object properties automatically). However, if you want to modify or add to these data object classes, the model is the place to do it.\n!!Views\nViews control the display of information. The provide the HTML framework within which data can be displayed. Processing information should be kept to a minimum in these pages. They are usually rhtml pages, which are html pages with ruby includes.\n!!!Layouts\nLayouts are special view files that act as templates within which other files are presented. These make it much easier to contruct a common appearance throughout the application.\n!!!Partials\nFilenames start with an underscore "e.g. _form.rhtml". Used to provide includes for other views of commonly reused display code.\n!!Helpers\nProvide processing support to views. If you find yourself writing complex code in the view to do things like automate a dropdown list, you should move the code to the appropriate helper.\n!!Test\nRails has a rich test environment. Unit tests are particularly easy to set up and use.\n!!Config\nThe main file of interest is database.yml. This is where database links are set up. Other files found here are routes.rb (used to define URL mappings) and environment.rb (where running environment variables can be altered).\n!!Lib\nThis is the place to put modules. Modules are used to create objects and methods used throught the applicaiton.\n!!Db\nContains database files. Good place to store SQL used to create tables. However, also the place Migrations live. Migration files are ruby code used to generate, and update SQL tables. A useful tool that allows you to version control database structure.\n!!Public\nThe folder actually presented by the web server. Contains config files (e.g. dispatch.fcgi) some error documents (default 404 and 500 error pages), and image, javascript and style folders.\n!!Script\nContains useful tools such as generators, and the webrick.\n!!Log\nUnsurprisingly contains the log files. Beware - development logs can get very big (Gbs) very quickly.
!Notes on Ruby on Rails\nA guide to the Ruby language that underlies Rails, can be found here:\nhttp://whytheluckystiff.net/ruby/pickaxe/\n\nMy notes on installing and using the system can be found here: RubyOnRails and InstallRails\n\nNotes of RailsApplicationStructure can be found via this link.\n\nRakeMigration is splendid!! Greatly simplifies creation and updating database tables\n\nBuildARailsApp is a reference listing the sequence used to create a new application.\n\n!!External Application\n* FireExternalScript\n\n!!Database fields\n* All tables need an index field and that should be called id\n* Foreign keys link on other table's id and are called othertablename_id\n* Date fields should end with _on as in created_on\n* Time fields should end with _at as in processed_at\n* Fields called created_at or created_on will automatically be set to the timestamp of the rows creation time.\n* Fields called updated_at or updated_on will automatically be set to the timestamp of the latest modification. With this and the previous create_at behaviour, the timestamp is local time.\n\n!!yml files\nA number of config files (test fixtures and database connection) are yml files that are in YAML format. This format see tabs as special characters. Therefore, you must be very careful to use spaces rather than tabs!!!!\n\n!!Object names\nRuby needs no variable declarations. It uses simple naming conventions to denote the scope of variables. Examples: simple 'var' = local variable, '@var' = instance variable, '$var' = global variable. So it is also not necessary to use a tiresome 'self.' prepended to every instance member.\n\n!!Validation and errors.\nRails includes a number of built in validation tools that you can add to. For example:\n{{{\nvalidates_presence_of :product, :license, :purchased_on, :value, :years, :list_price\nvalidates_numericality_of :value, :years, :list_price\nvalidates_each :value, :list_price, :years, :renewal_paid do |model, attr, value|\n unless value.nil? || value = 0\n model.errors.add(attr, "must be positive")\n end\nend\n}}}\nAny failures are reported to via the errors object. They can be shown on the page via:\n{{{\n <% if error_messages_for(:contract) -%>\n <%= error_messages_for(:contract) %>\n <% end -%>\n}}}\nwhere :contract is the current model.\n\nYou can use CSS to control the appearance of these messages. The messages appear in a DIV block with an ID and class "Errorexplanation", in individual input fields are put into a block div class="fieldWithErrors"\n\n!!Numbers\nThere are two main types of numbers: Integers (whole numbers) and Floats (decimals). \n\nBe careful with division. If you divide an integer with an integer, Ruby returns an integer. This can result in odd results. For example:\n\n1 / 10 = 0\n\nIt cannon return 0.1 because that is not an integer. To be safe, if you want to divide, make sure at least one of the numbers is a float:\n\n1.0 / 10.0 = 0.1\n\n!!Currency\n* number_to_currency converts numbers to dollars. Use this to convert to currency in pounds\n\namt = 12.34\nnumber_to_currency(amt, :unit => "£")\n\n!! Strings\n* html_escape() or the short hand version h() ensures html tags are never interpreted thereby preventing tag and script insertion. Therefore this method should be used to process ALL data passed to the server from a form submission.\n* string.pluralize returns the plural version of a noun\n* string.downcase change string to lower case. sting.upcase does the oposite\n* sting.capitalize makes the first letter of sting a capital letter.\n\n!!Image tags\n* If you enter a relative link to a image file you will get errors because the path to the image changes depending on whether you connect via /app/controller/ or /app/controller/index. However, if you uses the Rails method image_tag(), Rails will sort out the path for you. By default this assumes images are in the /public/images folder.\n{{{\n<%= image_tag("image.jpg" , :class => "bevel", :size => "80x120") %>\n}}}\n* Rails assumes images are in .png format if no extension is given. Therefore always include the .gif and .jpg extensions for these files.\n\n!!SQL to class object\nRails maps lines in a SQL database to Ruby objects. Each column is mapped to an object attribute, so that if there is a column "date_shipped_on", there will be an object.date_shipped_on. The mapping also uses the column information to define the attibute type as follows:\n\n|!SQL Type|!Ruby Class|\n|int, integer|Fixnum|\n|decimal, numeric|Float|\n|interval, date|Date|\n|clob,blob,text|String|\n|float, double|Float|\n|char, varchar, string|String|\n|datetime, time|Time|\n|boolean|varies|\n\nRuby will automatically convert data in a cell to the appropriate type. For example, a timestamp in a datetime field will automatically be converted into a time. If you wish to access the underlying data directly, you can use the _before_type_cast postcript. So product.start_on may give you 10:30, but product.start_on_before_type_cast could give you 120.4375.\n\n!!!Boolean\nBoolean is difficult as it could be stored as 0/1, t/f, true/false. Ruby sees both 0 and "f" as true. Therefore, "if user.hasrights" will always pass if hasrights is a boolean field in the Users table. Instead you can use a ? to force correct function. "if user.hasrights?" will not process if hasrights is "0", "f", "false" or nil/empty.\n\n!!Set environment to Production.\nWith my virtual directory set up, the only way I could force the system to production was to edit the config/environment.rb file in the application and remove the comment marker # from the start of the line:\n{{{\nENV['RAILS_ENV'] ||= 'production'\n}}}\nI've since found that you can set the environment via:\n{{{\n<IfModule mod_fastcgi.c>\n FastCgiServer C:/web/depot/public/dispatch.fcgi -initial-env RAILS_ENV=development -processes 2 -idle-timeout 60\n FastCgiServer C:/web/demo/public/dispatch.fcgi -initial-env RAILS_ENV=development -processes 2 -idle-timeout 60\n</IfModule>\n}}}\nin httpd.conf. This solution is better.
!!Fixtures\nFixtures populate the test tables with test data. They are YAML files so you need to be careful with the formatting. I particular - no TABS!. Here is an example:\n{{{\nfirst:\n id: 1\n name: sold\n list_position: 1\n created_at: <%= 18.month.ago.strftime("%Y-%m-%d %H:%M:%S") %>\n updated_at: <%= 18.month.ago.strftime("%Y-%m-%d %H:%M:%S") %>\nanother:\n id: 2\n name: stock\n list_position: 5\n created_at: <%= 18.month.ago.strftime("%Y-%m-%d %H:%M:%S") %>\n updated_at: <%= 18.month.ago.strftime("%Y-%m-%d %H:%M:%S") %>\n}}}\nNote that the times have to be converted to SQL format and the auto-generated fields such as created_at, have to be entered in the fixture.\n\n!!The test itself\n* Your test method name must start "test_". For example test_name_present\n* You may also need to create the tables in the test schema. You can do this with:\n{{{\nrake environment RAILS_ENV=test db:migrate\n}}}\n\nHere is an example of a unit test\n{{{\nrequire File.dirname(__FILE__) + '/../test_helper'\n\nclass CustomerTest < Test::Unit::TestCase\n fixtures :customers, :stock_statuses, :stocks\n\n def setup\n @BuyLots = Customer.find(1)\n @BuyOne = Customer.find(2)\n @BuyNone = Customer.find(3)\n end\n\n def test_stock_count\n assert_equal @BuyLots.stock_count, 2\n assert_equal @BuyOne.stock_count, 1\n assert_equal @BuyNone.stock_count, 0\n assert_equal @BuyLots.stock_count("sold"), 2\n assert_equal @BuyLots.stock_count("rubbish"), 0\n end\n\n def test_avg_margin\n assert_equal @BuyLots.avg_margin, 0.5\n assert_equal @BuyOne.avg_margin, 0.5\n assert_equal @BuyNone.avg_margin, false\n end\n\nend\n}}}\n!!Running the test\nYou can run an individual test with:\n{{{\nRuby test/unit/test_name.rb\n}}}\nYou can run all unit tests with:\n{{{\nrake test:units\n}}}\nAll functional tests run when this is entered:\n{{{\nrake test:functionals\n}}}\n\n
!!Database Migration Tool\nI'm using this for the first time on the Approved Suppliers project. Migration allows you to use Ruby code to build database tables. The system has built in version control, allowing you to roll back changes. It also simplifies copying tables to the production database as all you have to do is:\n\nFrom http://www.emxsoftware.com/RubyOnRails/Ruby+on+Rails+Migrations+Explained\n\nCommand reference:\n* {{{rake db_schema_dump}}} – dumps an existing database to a Rails schema file which allows you to port an application to different database platforms. \n* {{{rake db_schema_import}}} – imports the schema dumped using db_schema_dump\n* {{{rake db:migrate}}} – migrates a database to the current version\n* {{{rake db:migrate VERSION=7}}} – migrates a database to version 7\n* {{{rake environment RAILS_ENV=production db:migrate}}} – migrates the production database to the current version\n* {{{rake schema_generator}}} – products a .SQL file for each supported database platform (not everything is currently supported)\n\nSee also:\n* http://wiki.rubyonrails.org/rails/pages/UsingMigrations\n* http://api.rubyonrails.com/classes/ActiveRecord/Migration.html
* PaginationUpdate : Use will_paginate gem as pagination no longer a core element.\n* FormTags : start_form_tag and end_form_tag are no longer supported\n* Replace @flash with flash. e.g. @flash[:notice] becomes flash[:notice]
The MySQL admin tools allows you to schedule backups of the MySQL database. You can also create a batch file to do the same:\n{{{\nmysqldump -u root --password=your_password --all-databases > c:/backup/mysql.sql\n}}}\nHowever, restoring from that file isn't straight forward. The best way I found was to:\n# create a new .sql text file for each schema\n# copy the text for each scheme from the main backup file to the schema .sql file\n# remove any code that might cause an error. I removed: DROP and ALTER TABLE statements.\n# Manually recreate the schema\n# Use the command line to restore each schema individually (see below)\n# manually recreate the users.\n{{{\nmysql -h localhost -u root -p schema_name < schema.sql\n}}}\nYou will need to replace "schema_name" and "schema.sql" with the actual values you used.\n\n
To update from previous version you need to be on Ruby 1.8.4 at least. Then from the command prompt:\n{{{\ngem install rails --include-dependencies\n}}}\nThat updates the main Rails installation.\n\nThen you need to update applications with:\n{{{\nrake rails:update\n}}}\nRun from the application folder.\n//30-Mar-06//\nUpdate went fine. Some comments on notice boards concerning problems with plug-in. However, I am only running two at the moment (for file upload and RubyMonth) and the update seems to be fine.\n\n//27-May-08//\nSee UpgradingToRailsV2
I need LDAP to allow Rails application to talk to the Active Directory and pull user names from it. I'm looking at using [[ActiveLDAP|http://raa.ruby-lang.org/project/ruby-activeldap/]]. However this does have some prerequisites:\n!! log4r. Install using \n{{{\ngem install log4r\n}}}\n\n!!Ruby 1.8.1. \nWhich is already installed.\n\n!!Ruby/LDAP. \nLinux version:\nDownload from http://sourceforge.net/project/showfiles.php?group_id=66444\n\nWindows version see this:\nhttp://www.ruby-forum.com/topic/62584\n\n!!Installed ActiveLDAP with:\n{{{\ngem install ruby-activeldap\n}}}
//I'm not using this as a standard plug-in. It is there if I need to use it. Currently I'm avoiding using plug-ins if I can. 12-Apr-06//\n\nFrom out of murky depths of the Lafcadio codebase, I bring you a tiny\nutility library called Ruby Month. It's a modest thing, intended to\nmake month-level manipulations easier.\n\nhttp://rubyforge.org/projects/month\n\nFor example:\n{{{\nrequire 'month'\njun2005 = Month.new( 2005, 6 )\njun2005.to_s # => "Jun 2005"\njun2005.start_date.to_s # => "2005-06-01"\njun2005.end_date.to_s # => "2005-06-30"\n\njul2005 = jun2005.next\njul2005.to_s # => "Jul 2005"\nmay2005 = jun2005.prev\nmay2005.to_s # => "May 2005"\n\nto_sort = [ jul2005, may2005, jun2005 ]\nto_sort.join ', ' # => "Jul 2005, May 2005, Jun\n2005"\nto_sort.sort!\nto_sort.join ', ' # => "May 2005, Jun 2005, Jul\n2005"\n}}}\nHope you find it useful!\n\nFrancis Hwang\nhttp://fhwang.net/\n\nI installed it using the *.gem download:\n\ngem install month-0.1.0.gem\n\nMore documentation here:\n\nhttp://month.rubyforge.org/\n\nAlso\n{{{\njun2005 = Month.new( 2005, 6 )\njun2005.month # => 6\n}}}\n\n
!!Grabbing data from the interent\nThis code grabs a page from the internet (the Ruby license) and prints it to the console.\n{{{\nrequire 'net/http'\nNet::HTTP.start( 'www.ruby-lang.org', 80 ) do |http|\nprint( http.get( '/en/LICENSE.txt' ).body )\nend\n}}}
Information about Ruby on Rails can be found here:\nhttp://www.rubyonrails.org/ and here http://www.rubyonrails.com/\n//There can be variations between the two!//\n\nMy notes are here: RailsNotes, RailsTests\n\nInstallRails\n\nRuby is an object orientated scripting language. Rails is a frame work that allows rapid development of web applications using the Ruby language. The current installation of Ruby, also installs a help file: Programmingruby.chm. This is in effect an electronic version of the book "Programming Ruby: The Pragmatic Programmer's Guide"\n\nThe main problem I had was getting Rail to work on Apache (default is for Rails to use WeBrick). Following instructions on this page got me almost there (once I'd corrected an ommission):\n\nhttp://wiki.rubyonrails.org/rails/pages/Fast+CGI+and+Apache2+for+Windows+XP\n\nI choose to use Apache 1.3.x as guides indicated this was easier. That meant using mod_fastcgi-2.4.2-AP13.dll. See FastCGI.\n\nRubyforapache installs a module file mod_fastcgi.so. I can't see how this is connected to Apache or Ruby. However, if I uninstall it, Rails stops working. Installing the Rubyforapache app into the "Apache Group" folders worked for me.\n\nInstead of using a virtual host, I used an alias. To do this I added this code to Apache's http.conf:\n{{{\nAlias /demo/ "C:/web/demo/public/" \n\n<Directory "C:/web/demo/public/">\n AddHandler fastcgi-script .fcgi\n Options +ExecCGI +FollowSymLinks\n AllowOverride all\n Allow from all\n Order allow,deny\n</Directory>\n}}}\nWhich creates an alias for an application called "demo". \n\nYou also have to update .htaccess in the applications public folder. Here is a copy of an updated .htaccess for the demo application:\n{{{\n# General Apache options\n#AddHandler fastcgi-script .fcgi\n#AddHandler cgi-script .cgi\n#Options +FollowSymLinks +ExecCGI\n\n# If you don't want Rails to look in certain directories,\n# use the following rewrite rules so that Apache won't rewrite certain requests\n# \n# Example:\n# RewriteCond %{REQUEST_URI} ^/notrails.*\n# RewriteRule .* - [L]\n\n# Redirect all requests not available on the filesystem to Rails\n# By default the cgi dispatcher is used which is very slow\n# \n# For better performance replace the dispatcher with the fastcgi one\n#\n# Example:\n# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]\nRewriteEngine On\n\n# If your Rails application is accessed via an Alias directive,\n# then you MUST also set the RewriteBase in this htaccess file.\n#\n# Example:\n# Alias /myrailsapp /path/to/myrailsapp/public\n# RewriteBase /myrailsapp\n\nRewriteRule ^$ index.html [QSA]\nRewriteRule ^([^.]+)$ $1.html [QSA]\nRewriteCond %{REQUEST_FILENAME} !-f\n#RewriteRule ^(.*)$ dispatch.cgi [QSA,L]\nRewriteRule ^(.*)$ /demo/dispatch.fcgi [QSA,L]\n\n# In case Rails experiences terminal errors\n# Instead of displaying this message you can supply a file here which will be rendered instead\n# \n# Example:\n# ErrorDocument 500 /500.html\n\nErrorDocument 500 "<h2>Application error</h2>Rails application failed to start properly"\n}}}\nThe key difference to that generated by Rails is the commenting out of the first four lines and the commenting out of this line:\n{{{\n#RewriteRule ^(.*)$ dispatch.cgi [QSA,L]\n}}}\nand addition of this line:\n{{{\nRewriteRule ^(.*)$ /demo/dispatch.fcgi [QSA,L]\n}}}\nMore information on this way of setting up Apache can be found here:\n\nhttp://wiki.rubyonrails.org/rails/pages/Fast+CGI+and+Apache2+for+Windows+without+VirtualHosts\n\nI am currently working my way through the book [[Agile Web Development with Rails|http://www.pragmaticprogrammer.com/titles/rails/index.html]]\n\n//9-Mar-06//\nI've finished the main tutorial in the book and also advanced chapters on security and linking tables/foreign keys. I haven't read all the book but feel I'm ready to start building apps.\n\nTherefore, I've started my first serious app: ConTrack - a contract tracking system.\n\nhttp://www.sitepoint.com/forums/ looks to be a useful Ruby (and others) forum.\n\nI've added a module to Ruby to improve the way it handles months. See RubyMonth\n\n//4-Apr-06//\nMy first Rail application is now on-line and set for production environment. I've found that each FastCGI instance runs a Ruby environment. This eats up memory. Also it takes a while to fire up a Ruby instance if the last one has closed, or on restart. This code in Apache's config file (httpd.conf) fixes the problems:\n{{{\n<IfModule mod_fastcgi.c>\n FastCgiServer C:/web/depot/public/dispatch.fcgi -initial-env RAILS_ENV=production -processes 2 -idle-timeout 60\n FastCgiServer C:/web/demo/public/dispatch.fcgi -initial-env RAILS_ENV=development -processes 2 -idle-timeout 60\n</IfModule>\n}}}\nNote that this has specified the behaviour for two apps. Apps not specified behave in the default manner, with Apache opening and closing Ruby instances as it see fit (via FastCGI). Note also that this is the place to specify the RAIL running environment. Production environment is significantly faster than production, using features such as caching to improve speed.
To install and use SQLite as the database:\n\nSee http://wiki.rubyonrails.com/rails/pages/HowtoUseSQLite\n\nGet the Windows binaries from: \nhttp://www.sqlite.org/download.html\n\nYou need both the exe and the dll. Three files in total: sqlite3.dll; sqlite3.def; and sqlite3.exe. Add them to your ruby bin folder (e.g. c:\sruby\sbin)\n\nThen install the Ruby SQLite library\n{{{\ngem install sqlite3-ruby\n}}}\nThe database.yml entry needs to be:\n{{{\nproduction:\n adapter: sqlite3\n database: db/production.sqlite3\n}}}\n
{{{\nUsage: script/generate scaffold ModelName [ControllerName] [action, ...]\n\n\nGeneral Options:\n -p, --pretend Run but do not make any changes.\n -f, --force Overwrite files that already exist.\n -s, --skip Skip files that already exist.\n -q, --quiet Suppress normal output.\n -t, --backtrace Debugging: show backtrace on errors.\n -h, --help Show this help message.\n -c, --svn Modify files with subversion. (Note: svn must be in path)\n\nDescription:\n The scaffold generator creates a controller to interact with a model.\n If the model does not exist, it creates the model as well. The generated\n code is equivalent to the "scaffold :model" declaration, making it easy\n to migrate when you wish to customize your controller and views.\n\n The generator takes a model name, an optional controller name, and a\n list of views as arguments. Scaffolded actions and views are created\n automatically. Any views left over generate empty stubs.\n\n The scaffolded actions and views are:\n index, list, show, new, create, edit, update, destroy\n\n If a controller name is not given, the plural form of the model name\n will be used. The model and controller names may be given in CamelCase\n or under_score and should not be suffixed with 'Model' or 'Controller'.\n Both model and controller names may be prefixed with a module like a\n file path; see the Modules Example for usage.\n\nExample:\n ./script/generate scaffold Account Bank debit credit\n\n This will generate an Account model and BankController with a full test\n suite and a basic user interface. Now create the accounts table in your\n database and browse to http://localhost/bank/ -- voila, you're on Rails!\n\nModules Example:\n ./script/generate scaffold CreditCard 'admin/credit_card' suspend late_fee\n\n This will generate a CreditCard model and CreditCardController controller\n in the admin module.\n}}}
or ReggieB's ramblings
Rob's Ruby on Rails notes
!Subversion version control\nSubversion or svn is a version control system similar in function to Sourcesafe. I'm installing it on Miggins as I think it better suits the tree structure of my Ruby on Rails projects.\n\nThese is an interesting article on subversion here:\nhttp://www.regdeveloper.co.uk/2006/03/23/subversion_perforce/\n\n!!Installation and configuration.\nI've down loaded and installed the Subversion application on Miggins via the exe on:\nhttp://subversion.tigris.org/project_packages.html\n\nI've then set up a repository on the F: drive using the commands:\n{{{\nmkdir f:\svn-repos\nsvnadmin create f:\svn-repos\n}}}\nI've then downloaded an application that runs the network version of Subversion as a windows service and installed those files into Subversion bin folder. I was then able to create the this service - SVNService - using this command:\n{{{\nSVNService -install -d -r f:\svn-repos\n}}}\nI then used the service tool in Windows control panel to set the service to Automatic (so that it starts at boot) and start the service to make sure all is well so far.\n\nYou use:\n{{{\nsc delete SVNService\n}}}\nTo delete the service. Note that sc can delete any service.\n\n!!Import current project\nI then imported the Contrack project into the repository using the command:\n{{{\nsvn -m "Import working RubyRails Contrack project" . file:///f:/svn-repos/contrack/version1\n}}}\n(The command was run from the Contrack folder. The dot tells svn to import the current folder)\n\n!!Set permissions\nTwo server files needed to be editted.\nsvnserve.conf was changed so that these lines were the only active ones (not commented out).\n{{{\n[general]\nanon-access = read\nauth-access = write\npassword-db = passwd\n}}}\n\nThe file passwd was editted and these entries made the only active ones:\n{{{\n[users]\nrobn = password\n}}}\n\nUntil these files were editted, the repository was read only. The set up above allow anyone to read the repository, but only robn can write to the repository via the network connection. \n\n!!Client access\nI accessed and controlled the working files with TortoiseSVN\n\n!!Setting system to Ignore files that don't need to be versioned\nYou can use svn:ignore to exclude files from the repository. For example:\n{{{\nsvn propset svn:ignore "*" tmp/\n}}}\nWill set up the system so that it ignores all files in the tmp folder.\n\nWith TortoiseSVN you can do the same using the following steps:\n* Right click on the tmp folder and select properties from the TortoiseSVN submenu (not properties on the main menu).\n* Click on the "New" button\n* Select "svn:ignore" from the Property Name drop down\n* Enter * as the property value. No quote marks around the *\n* Click on OK to close the Add window and OK again to close the properties window\n
An object for holding data without having to use a predefined dedicated class.\n\nSee these blog entries for details:\n\nhttp://nicholshayes.myzen.co.uk/blog/?p=31\n\nhttp://nicholshayes.myzen.co.uk/blog/?p=35\n\nhttp://nicholshayes.myzen.co.uk/blog/?p=50
!!The Rails Way\n\nA book by Obie Fernandez.\n\nhttp://www.informit.com/store/product.aspx?isbn=0321445619
This wiki is created using a Tiddly Wiki - a splendid JavaScript driven personal wiki app.\n\nHome page is here: [[www.tiddlywiki.org|http://www.tiddlywiki.org/]]\n\nGuide to the markup is [[here|http://www.tiddlywiki.org/wiki/TiddlyWiki_Markup]]\n\n
TortoiseSVN is a Windows Subversion client. You can get it here:\n\nhttp://tortoisesvn.tigris.org/\n\nThis website also give a lot of information on how the system works.
!!!First time through on test/development system\n\nTo start the process of upgrading from 2.0.2 to 2.2.2:\n{{{\ngem update rails\n}}}\nTo update the core Rails install.\n\nThen update each application by running this in the root of each application:\n{{{\nrake rails:update\n}}}\n\nOn trying to start a server received message that gems wasn't right version so then ran this to update gems:\n{{{\ngem update --system\n}}}\n\nOn trying server (webrick) start again got an error regarding an undefined variable cache_template_extensions. The solution to this error was to remove\n{{{\ncache_template_extensions = false\n}}}\nfrom config/environments/development.rb\n\nWebrick now started. However, when I try to access a page I get a message stating that the mysql driver has been removed from rails. To fix:\n{{{\ngem install mysql\n}}}\n\nThen tried mongrel and got gems errors:\nhttp://rubyforge.org/tracker/index.php?func=detail&aid=15817&group_id=1306&atid=5145\nUninstalling and reinstalling mongrel and mongrel_service fixed the problem:\n{{{\ngem uninstall mongrel_service\ngem uninstall mongrel\ngem install mongrel\ngem install mongrel_service\n}}}\n\n!!!On the server\nI pretty much followed the same sequence on the server without the cache_template_extensions update as that was already done. Also initially I didn't run rails:update in each app as I assumed that any changes would come over with the application code, but when I hit problems I did run this command on the server too.\n\nI hit a problem with MySQL version. Rails now need the mysql gem, and this wouldn't work with MySQL 4. So I had to upgrade to 5.0. The latest version (5.0.77) wouldn't work with the gem (see: http://www.ruby-forum.com/topic/179601). Downgrading to 5.0.18 fixed the problem.
Update was carried out on Vista Business. There seem to be a number of nice feature available in this version so worth the effort I think:\n\nhttp://guides.rubyonrails.org/2_3_release_notes.html\n\nAs found previously (UpdateRailsTo2.2.2), System wouldn't work with latest MySQL. So installed 5.0.18\n\n2.3.4 changed application.rb to application_controller.rb. \n{{{\nrake rails:update\n}}}\nfixes this problem - but of course makes the application incompatible with early versions of Rails.\n\nForgot to install will-paginate plugin - but worked via gems (once pointed at github)\n\nAlso needed to install MicrosoftSQL gem\n{{{\ngem install activerecord-sqlserver-adapter\n}}}\nAnd the get the ADO object (see MicrosoftSQL)\n\nHowever see notes in MicrosoftSQL re: uninstalling dbi gem and reinstalling it.\n\n!!!Unit tests\nUnit tests have changes a little. You now have to alter \n{{{\nTest::Unit::TestCase\n}}}\nto\n{{{\nActiveSupport::TestCase\n}}}\nIn each application's test_helper.rb\n{{{\nclass ActiveSupport::TestCase\n}}}\nAnd each unit test\n{{{\nclass AddressTest < ActiveSupport::TestCase\n}}}
The will_paginate project has changed name and also changed the name of its gem. The gem is now mislav-will_paginate. Therefore you have to uninstall will_paginate and then install the mislav-will_paginate gem to update will_paginate. So:\n{{{\ngem uninstall will_paginate\n\ngem sources -a http://gems.github.com\n\ngem install mislav-will_paginate\n}}}\nInformation on will_paginate can be found here:\nhttp://github.com/mislav/will_paginate/wikis
First uninstall Ruby\n\nInstall Ruby 1.8.6 using one click installer\n\n{{{\ngem install rails --include-dependencies\n}}}\nReinstall the MS SQL adapter: MicrosoftSQL\n\nReinstall Mongrel\n{{{\ngem install mongrel_service --include-dependencies\n}}}\nAccept all dependencies.\n\nAdd this line to config/environment.rb\n{{{\nconfig.action_controller.session = { :session_key => "_myapp_session", \n :secret => "A phrase at least 30 characters long" }\n}}}\nNotice that whoshe and crumb need to use the same secret!!!\n\nAdd the ruby/bin folder to the system path (semi-colons separate entries in Path statement).\n\nReinstall the Rmagick gem (see [[Graphics]] post)\n\nDebug errors that occur due to version 1 functions being depreciated.\nsee RefactoringNeededForRails2\n\nWhich includes installed will_paginate\n{{{\ngem install will_paginate\n}}}\n
!!Creating a plug-in called more_array_methods\nAn example of how I used a plug-in to extend a core Ruby class within an application. Based on this example:\nhttp://wiki.rubyonrails.com/rails/pages/HowToWriteAnActsAsFoxPlugin\n!!The process - how I did it.\n{{{\nruby script/generate plugin more_array_methods\n}}}\nThis created a directory "vendor\splugins\smore_array_methods" and populated it with a number of files. Two of these needed to be modified:\n\n!!!init.rb\nThis file needs to include the code that will tie the new elements into the existing structure\n{{{\n# Include hook code here\nrequire 'more_array_methods'\n\nArray.class_eval do\n include MoreArrayMethods\nend\n}}}\n\n!!!lib\smore_array_methods.rb\nThis file contains the new code being added\n{{{\n#Extensions to basic Array class to provide extra functionality\nmodule MoreArrayMethods\n\n #Finds an element within an array and moves that element to position 0\n #Does nothing if element is not found\n # ['a', 'b', 'c'].move_to_front('b') --> ['b', 'a', 'c']\n # ['a', 'b', 'c'].move_to_front('B') --> ['b', 'a', 'c']\n # ['a', 'b', 'c'].move_to_front('x') --> ['a', 'b', 'c']\n #You can also pass a number of elements to the this method\n #Any matching elements will be brought to the front in the order they are entered\n #[1, 2, 3, 4, 5].move_to_front(3, 5, 6) --> [3, 5, 1, 2, 4]\n def move_to_front(*elements)\n for element in elements.reverse\n if element_position = caseless_index(element)\n unshift slice!(element_position)\n end\n end\n return self\n end\n\n #Finds an element within an array and moves that element to the end of the array\n #Does nothing if element is not found\n # ['a', 'b', 'c'].move_to_back('b') --> ['a', 'c', 'b']\n # ['a', 'b', 'c'].move_to_back('B') --> ['a', 'c', 'b']\n # ['a', 'b', 'c'].move_to_back('x') --> ['a', 'b', 'c']\n #You can also pass a number of elements to the this method\n #Any matching elements will be taken to the back in the order they are entered\n # [1, 2, 3, 4, 5].move_to_back(3, 5, 6) --> [1, 2, 4, 3, 5]\n def move_to_back(*elements)\n for element in elements\n if element_position = caseless_index(element)\n self << slice!(element_position)\n end\n end\n return self\n end\n\n #A case-insensitve version of index.\n #['a', 'b', 'c'].caseless_index('b') --> 1\n #['a', 'b', 'c'].caseless_index('B') --> 1\n #If array contains elements that are not strings, system uses standard index\n #['a', 1, 'c'].caseless_index(1) --> 1\n def caseless_index(element)\n if element.kind_of? String\n lower_case_copy_of_array = collect{|a| a.downcase}\n lower_case_copy_of_array.index(element.downcase)\n else\n index(element)\n end\n end\nend\n}}}\n\n!!Testing\nThe plug-in generator creates a unit test file. One thing I found with this is that I had to require init.rb before it would work. Also worth noting is that running the test as a Ruby application doesn't work. Instead, go to the root of the plugin and run:\n\n{{{\nrake test\n}}}\n \nHere is the test:\n!!!test/more_array_methods_test.rb\n{{{\nrequire 'test/unit'\nrequire 'init'\n\nclass MoreArrayMethodsTest < Test::Unit::TestCase\n # Replace this with your real tests.\n def setup\n @number_array = [1, 2, 3, 4, 5]\n @text_array = %w{a b c}\n end\n\n def test_move_to_back\n a = @number_array.clone\n assert_equal a.move_to_back(3), [1, 2, 4, 5, 3]\n a = @number_array.clone\n assert_equal a.move_to_back(3, 5, 6), [1, 2, 4, 3, 5]\n b = @text_array.clone\n assert_equal b.move_to_back("A"), %w{b c a}\n end\n\n def test_move_to_front\n a = @number_array.clone\n assert_equal a.move_to_front(3), [3, 1, 2, 4, 5]\n a = @number_array.clone\n assert_equal a.move_to_front(3, 5, 6), [3, 5, 1, 2, 4]\n b = @text_array.clone\n assert_equal b.move_to_front("C"), %w{c a b}\n end\n\n def test_caseless_index\n assert_equal @number_array.caseless_index(2), @number_array.index(2)\n assert_equal @text_array.caseless_index("B"), @text_array.index("b")\n assert_equal @text_array.caseless_index("b"), @text_array.index("b")\n assert_equal @text_array.caseless_index("x"), nil\n end\n\nend\n}}}\n\n!!Notes\nOne thing that makes this hard work is that changes to the plug-in only become effective within the application after the application is restarted. I also found it quite difficult to test this functionality at the console. So you have to restart the mongrel/webrick server a lot to get your code working correctly.
WEBrick is the Ruby HTTP server that is bundled with Rails. To start WEBrick on a Windows platform I navigate to the application folder at the command prompt and use the command:\n{{{\nruby script/server\n}}}\nWEBrick then starts and listens on port 3000. You can access your application with:\n{{{\nhttp://localhost:3000/\n}}}\nTo start in production mode:\n{{{\nruby script/server -e production\n}}}\nTo open on another port (e.g. 3001) use:\n{{{\nruby script/server -p 3001\n}}}
!WhoShe\nA web application to replace Goldmine and act as the core of future Intranet applications.\n\n//9-Mar-06 Project currently on hold while I development my RubyOnRails skill on a couple of simpler projects (see ConTrack and JobCode)//\n\n!!Stage one : design the data model\nI've put together a data framework on my new white board. The core difference to Goldmine in the new model is the grouping of contacts into office and company. Each contact will be a person, in an office, which is part of a company. No longer will each person in a company have their own independant set of full contact information (the problem being that it is difficult to update them all if there is a change at the company level. For example, a change of switchboard number. Also it is difficult to tie all the dealings with a company together). Each person will be represented as company.office.person.\n\n!!Stage two: select the application environment.\nMySQL is the obvious database choice. \n\nI've selected RubyOnRails as the application scripting language, as it is object driven, straightforward to develop, and builds on my HTML, JavaScript and CSS skill.\n\nApache is the obvious web server to use with RubyOnRails. However, I will attempt to use IIS as this will make better use of the name space. (Apache will have to run on a port other than 80 if it and IIS are to run together).\n\n!!Stage three: build prototype\nI am currently developing my Ruby skills to get me up to speed.
{{{\npagination_navigation(pages, window_size=10, args={})\n}}}\nI've created an application helper method to simplify the addition of pagination links onto a list. For a simple example:\n{{{\n<%= pagination_navigation(@expense_claim_pages, 10) %>\n}}}\nCreates a simple set of links for each page that looks something like this:\n{{{\nPrevious page 1 2 3 Next page \n}}}\nThis example comes from the stock list and shows how you can add parameters that appear with each link:\n{{{\n<%= pagination_navigation(@stock_pages, 10, {:status => params[:status], :product => params[:product]}) %>\n}}}\nProduces this:\n{{{\n<p>\n1 <a href="/suppliers/show/22?page=2&status=show_all">2</a> \n<a href="/suppliers/show/22?page=2&status=show_all">Next page</a>\n</p>\n}}}\nIn this example only a status was present in params. A 'Next page' link is shown below that resulted when both a product and status were present in params:\n{{{\n<a href="/suppliers/show/12?page=2&product=Druck+PTX1830&status=Sold">Next page</a>\n}}}\nNote, only a status was passed to this example.