David Heinemeier Hansson
2004-Oct-25 02:24 UTC
[ANN] Rails 0.8: Just shy of 100 additions, changes, tweaks, and fixes!
It''s been fifty days since our last confession, so it''s no wonder that this outpouring is by far the biggest yet in Rails history. It''s absolutely packed with goodies ranging from a whole new framework for sending email to the smallest new alias for an existing method. In total we''re just shy of 100 additions, changes, tweaks, and fixes. This is also the release with the highest number of contributors. I''ve counted at least 23 different people with patches in Rails 0.8 -- and there are many, many more responsible for suggestions and bug reports. This is truely turning into a community movement and I''m extremely pleased to be the steward for it. Get it all from http://www.rubyonrails.org, talk it up on #rubyonrails (FreeNet). Or even easier, just do "gem install rails" (or "gem update" if you''re already running on Gem Rails) -- you''ll automatically install all the newest versions of the required dependencies. (NOTE: Wait 40 minutes from this mail went out, so the gem repository is in synch -- couldn''t we check every 15 minutes instead of every hour :)?) Commercial announcement: If you''re looking for a place to host your Rails project or just to play around with it online, we now have an official hosting partner in TextDrive. I''m on board to ensure that the Rails experience is top notch and in return 50% of the gross profits are going to help further Rails. Read more on: http://www.rubyonrails.org/show/TextDriveHosting Rails 0.8.0: Multi-word classes are now welcome, WEBrick binding =============================================================== * Removed custom_table_name option for new_model now that the Inflector is as powerful as it is * Changed the default rake action to just do testing and separate API generation and coding statistics into a "doc" task. * Fixed WEBrick dispatcher to handle missing slashes in the URLs gracefully [alexey] * Added user option for all postgresql tool calls in the rakefile [elvstone] * Fixed problem with running "ruby public/dispatch.servlet" instead of "cd public; ruby dispatch.servlet" [alexey] * Fixed WEBrick server so that it no longer hardcodes the ruby interpreter used to "ruby" but will get the one used based on the Ruby runtime configuration. [Marcel Molina Jr.] * Fixed Dispatcher so it''ll route requests to magic_beans to MagicBeansController/magic_beans_controller.rb [Caio Chassot] * "new_controller MagicBeans" and "new_model SubscriptionPayments" will now both behave properly as they use the new Inflector. * Fixed problem with MySQL foreign key constraint checks in Rake :clone_production_structure_to_test target [Andreas Schwarz] * Changed WEBrick server to by default be auto-reloading, which is slower but makes source changes instant. Class compilation cache can be turned on with "-c" or "--cache-classes". * Added "-b/--binding" option to WEBrick dispatcher to bind the server to a specific IP address (default: 127.0.0.1) [Kevin Temp] * dispatch.fcgi now DOESN''T set FCGI_PURE_RUBY as it was slowing things down for now reason [Andreas Schwarz] * Added new_mailer generator to work with Action Mailer * Included new framework: Action Mailer 0.3 * Upgraded to Action Pack 0.9.0 * Upgraded to Active Record 1.0.0 Action Mailer 0.3: Easy email delivery and testing ================================================= Action Mailer is framework for designing email-service layers. These layers are used to consolidate code for sending out forgotten passwords, welcoming wishes on signup, invoices for billing, and any other use case that requires a written notification to either a person or another system. The framework works by setting up all the email details, except the body, in methods on the service layer. Subject, recipients, sender, and timestamp are all set up this way. An example of such a method: def signed_up(recipient) @recipients = recipient @subject = "[Signed up] Welcome #{recipient}" @from = "system-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org" @sent_on = Time.local(2004, 12, 12) @body["recipient"] = recipient end The body of the email is created by using an Action View template (regular ERb) that has the content of the @body hash available as instance variables. So the corresponding body template for the method above could look like this: Hello there, Mr. <%= @recipient %> And if the recipient was given as "david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org", the email generated would look like this: Date: Sun, 12 Dec 2004 00:00:00 +0100 From: system-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org To: david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org Subject: [Signed up] Welcome david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org Hello there, Mr. david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org You never actually call the instance methods like signed_up directly. Instead, you call class methods like deliver_* and create_* that are automatically created for each instance method. So if the signed_up method sat on ApplicationMailer, it would look like this: ApplicationMailer.create_signed_up("david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org") # => tmail object for testing ApplicationMailer.deliver_signed_up("david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org") # sends the email ApplicationMailer.new.signed_up("david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org") # won''t work! Active Record 1.0.0: Easy email delivery and testing =================================================== * Added OO-style associations methods [Florian Weber]. Examples: Project#milestones_count => Project#milestones.size Project#build_to_milestones => Project#milestones.build Project#create_for_milestones => Project#milestones.create Project#find_in_milestones => Project#milestones.find Project#find_all_in_milestones => Project#milestones.find_all * Added serialize as a new class method to control when text attributes should be YAMLized or not. This means that automated serialization of hashes, arrays, and so on WILL NO LONGER HAPPEN (#10). You need to do something like this: class User < ActiveRecord::Base serialize :settings end This will assume that settings is a text column and will now YAMLize any object put in that attribute. You can also specify an optional :class_name option that''ll raise an exception if a serialized object is retrieved as a descendent of a class not in the hierarchy. Example: class User < ActiveRecord::Base serialize :settings, :class_name => "Hash" end user = User.create("settings" => %w( one two three )) User.find(user.id).settings # => raises SerializationTypeMismatch * Added the option to connect to a different database for one model at a time. Just call establish_connection on the class you want to have connected to another database than Base. This will automatically also connect decendents of that class to the different database [Renald Buter]. * Added transactional protection for Base#save. Validations can now check for values knowing that it happens in a transaction and callbacks can raise exceptions knowing that the save will be rolled back. [Suggested by Alexey Verkhovsky] * Added column name quoting so reserved words, such as "references", can be used as column names [Ryan Platte] * Added the possibility to chain the return of what happened inside a logged block [geech]: This now works: log { ... }.map { ... } Instead of doing: result = [] log { result = ... } result.map { ... } * Added "socket" option for the MySQL adapter, so you can change it to something else than "/tmp/mysql.sock" [Anna Liss Cruz] * Added respond_to? answers for all the attribute methods. So if Person has a name attribute retrieved from the table schema, person.respond_to? "name" will return true. * Added Base.benchmark which can be used to aggregate logging and benchmark, so you can measure and represent multiple statements in a single block. Usage (hides all the SQL calls for the individual actions and calculates total runtime for them all): Project.benchmark("Creating project") do project = Project.create("name" => "stuff") project.create_manager("name" => "David") project.milestones << Milestone.find_all end * Added logging of invalid SQL statements [Suggested by Daniel Von Fange] * Added alias Errors#[] for Errors#on, so you can now say person.errors["name"] to retrieve the errors for name [Andreas Schwarz] * Added RubyGems require attempt if sqlite-ruby is not available through regular methods. * Added compatibility with 2.x series of sqlite-ruby drivers. [Jamis Buck] * Added type safety for association assignments, so a ActiveRecord::AssociationTypeMismatch will be raised if you attempt to assign an object that''s not of the associated class. This cures the problem with nil giving id = 4 and fixnums giving id = 1 on mistaken association assignments. [Reported by Andreas Schwarz] * Added the option to keep many fixtures in one single YAML document [what-a-day] * Added the class method "inheritance_column" that can be overwritten to return the name of an alternative column than "type" for storing the type for inheritance hierarchies. [Dave Steinberg] * Added [] and []= as an alternative way to access attributes when the regular methods have been overwritten [Dave Steinberg] * Added the option to observer more than one class at the time by specifying observed_class as an array * Added auto-id propagation support for tables with arbitrary primary keys that have autogenerated sequences associated with them on PostgreSQL. [Dave Steinberg] * Changed that integer and floats set to "" through attributes= remain as NULL. This was especially a problem for scaffolding and postgresql. (#49) * Changed the MySQL Adapter to rely on MySQL for its defaults for socket, host, and port [Andreas Schwarz] * Changed ActionControllerError to decent from StandardError instead of Exception. It can now be caught by a generic rescue. * Changed class inheritable attributes to not use eval [Caio Chassot] * Changed Errors#add to now use "invalid" as the default message instead of true, which means full_messages work with those [Marcel Molina Jr] * Fixed spelling on Base#add_on_boundry_breaking to Base#add_on_boundary_breaking (old naming still works) [Marcel Molina Jr.] * Fixed that entries in the has_and_belongs_to_many join table didn''t get removed when an associated object was destroyed. * Fixed unnecessary calls to SET AUTOCOMMIT=0/1 for MySQL adapter [Andreas Schwarz] * Fixed PostgreSQL defaults are now handled gracefully [Dave Steinberg] * Fixed increment/decrement_counter are now atomic updates [Andreas Schwarz] * Fixed the problems the Inflector had turning Attachment into attuchments and Cases into Casis [radsaq/Florian Gross] * Fixed that cloned records would point attribute references on the parent object [Andreas Schwarz] * Fixed SQL for type call on inheritance hierarchies [Caio Chassot] * Fixed bug with typed inheritance [Florian Weber] * Fixed a bug where has_many collection_count wouldn''t use the conditions specified for that association Action Pack 0.9.0: Builder-based templates, functional testing, performance ======================================================================== == * Added support for Builder-based templates for files with the .rxml extension. These new templates are an alternative to ERb that are especially useful for generating XML content, such as this RSS example from Basecamp: xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do xml.channel do xml.title(@feed_title) xml.link(@url) xml.description "Basecamp: Recent items" xml.language "en-us" xml.ttl "40" for item in @recent_items xml.item do xml.title(item_title(item)) xml.description(item_description(item)) if item_description(item) xml.pubDate(item_pubDate(item)) xml.guid(@person.firm.account.url + @recent_items.url(item)) xml.link(@person.firm.account.url + @recent_items.url(item)) xml.tag!("dc:creator", item.author_name) if item_has_creator?(item) end end end end ...which will generate something like: <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> <title>Web Site Redesign</title> <link>http://www.basecamphq.com/clients/travelcenter/1/</link> <description>Basecamp: Recent items</description> <language>en-us</language> <ttl>40</ttl> <item> <title>Post: don''t you know</title> <description>&lt;p&gt;deeper and down&lt;/p&gt;</description> <pubDate>Fri, 20 Aug 2004 21:13:50 CEST</pubDate> <guid>http://www.basecamphq.com/clients/travelcenter/1/msg/assets/ 96976/comments</guid> <link>http://www.basecamphq.com/clients/travelcenter/1/msg/assets/ 96976/comments</link> <dc:creator>David H. Heinemeier</dc:creator> </item> <item> <title>Milestone completed: Design Comp 2</title> <pubDate>Mon, 9 Aug 2004 14:42:06 CEST</pubDate> <guid>http://www.basecamphq.com/clients/travelcenter/1/milestones/#49</ guid> <link>http://www.basecamphq.com/clients/travelcenter/1/milestones/#49</ link> </item> </channel> </rss> The "xml" local variable is automatically available in .rxml templates. You construct the template by calling a method with the name of the tag you want. Options for the tag can be specified as a hash parameter to that method. Builder-based templates can be mixed and matched with the regular ERb ones. The only thing that differentiates them is the extension. No new methods have been added to the public interface to handle them. Action Pack ships with a version of Builder, but it will use the RubyGems version if you have one installed. Read more about Builder on: http://onestepback.org/index.cgi/Tech/Ruby/StayingSimple.rdoc [Builder is created by Jim Weirich] * Added much improved support for functional testing [what-a-day]. # Old style def test_failing_authenticate @request.request_uri = "/login/authenticate" @request.action = "authenticate" @request.request_parameters["user_name"] = "nop" @request.request_parameters["password"] = "" response = LoginController.process_test(@request) assert_equal "The username and/or password you entered is invalid.", response.session["flash"]["alert"] assert_equal "http://37signals.basecamp.com/login/", response.headers["location"] end # New style def test_failing_authenticate process :authenticate, "user_name" => "nop", "password" => "" assert_flash_has ''alert'' assert_redirected_to :action => "index" end See a full example on http://codepaste.org/view/paste/334 * Increased performance by up to 100% with a revised cookie class that fixes the performance problems with the default one that ships with 1.8.1 and below. It replaces the inheritance on SimpleDelegator with DelegateClass(Array) following the suggestion from Matz on: http://groups.google.com/groups? th=e3a4e68ba042f842&seekm=c3sioe%241qvm%241%40news.cybercity.dk#link14 * Added caching for compiled ERb templates. On Basecamp, it gave between 8.5% and 71% increase in performance [Andreas Schwarz]. * Added implicit counter variable to render_collection_of_partials [Marcel]. From the docs: <%= render_collection_of_partials "ad", @advertisements %> This will render "advertiser/_ad.rhtml" and pass the local variable +ad+ to the template for display. An iteration counter will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the example above, the template would be fed +ad_counter+. * Fixed problems with two sessions being maintained on reset_session that would particularly screw up ActiveRecordStore. * Fixed reset_session to start an entirely new session instead of merely deleting the old. So you can now safely access @session after calling reset_ression and expect it to work. * Added @request.get?, @request.post?, @request.put?, @request.delete? as convenience query methods for @request.method [geech] * Added @request.method that''ll return a symbol representing the HTTP method, such as :get, :post, :put, :delete [geech] * Changed @request.remote_ip and @request.host to work properly even when a proxy is in front of the application [geech] * Added JavaScript confirm feature to link_to. Documentation: The html_options have a special feature for creating javascript confirm alerts where if you pass :confirm => ''Are you sure?'', the link will be guarded with a JS popup asking that question. If the user accepts, the link is processed, otherwise not. * Added link_to_unless_current as a UrlHelper method [Sam Stephenson]. Documentation: Creates a link tag of the given +name+ using an URL created by the set of +options+, unless the current controller, action, and id are the same as the link''s, in which case only the name is returned (or the given block is yielded, if one exists). This is useful for creating link bars where you don''t want to link to the page currently being viewed. * Fixed that UrlRewriter (the driver for url_for, link_to, etc) would blow up when the anchor was an integer [alexey] * Added that layouts defined with no directory defaults to layouts. So layout "weblog/standard" will use weblog/standard (as always), but layout "standard" will use layouts/standard. * Fixed that partials (or any template starting with an underscore) was publically viewable [Marten] * Added HTML escaping to text_area helper. * Added :overwrite_params to url_for and friends to keep the parameters as they were passed to the current action and only overwrite a subset. The regular :params will clear the slate so you need to manually add in existing parameters if you want to reuse them. [raphinou] * Fixed scaffolding problem with composite named objects [Moo Jester] * Added the possibility for shared partials. Example: <%= render_partial "advertisement/ad", ad %> This will render the partial "advertisement/_ad.rhtml" regardless of which controller this is being called from. [Jacob Fugal] * Fixed crash when encountering forms that have empty-named fields [James Prudente] * Added check_box form helper method now accepts true/false as well as 1/0 [what-a-day] * Fixed the lacking creation of all directories with install.rb [Dave Steinberg] * Fixed that date_select returns valid XHTML selected options [Andreas Schwarz] * Fixed referencing an action with the same name as a controller in url_for [what-a-day] * Fixed the destructive nature of Base#attributes= on the argument [Kevin Watt] * Changed ActionControllerError to decent from StandardError instead of Exception. It can now be caught by a generic rescue. * Added SessionRestoreError that is raised when a session being restored holds objects where there is no class available. * Added block as option for inline filters. So what used to be written as: before_filter Proc { |controller| return false if controller.params["stop_action"] } ...can now be as: before_filter { |controller| return false if controller.params["stop_action"] } [Jeremy Kemper] * Made the following methods public (was protected): url_for, controller_class_name, controller_name, action_name This makes it easier to write filters without cheating around the encapsulation with send. * ActionController::Base#reset_session now sticks even if you access @session afterwards [Kent Sibilev] * Improved the exception logging so the log file gets almost as much as in-browser debugging. * Changed base class setup from AbstractTemplate/ERbTemplate to ActionView::Base. This change should be harmless unless you were accessing Action View directly in which case you now need to reference the Base class.\ * Added that render_collection_of_partials returns nil if the collection is empty. This makes showing a “no items” message easier. For example: <%= render_collection_of_partials("message", @messages) || "No messages found." %> [Sam Stephenson] * Added :month_before_year as an option to date_select to get the month select before the year. Especially useful for credit card forms. * Added :add_month_numbers to select_month to get options like "3 - March". * Removed Base.has_active_layout? as it couldn''t answer the question without the instance. Use Base#active_layout instead. * Removed redundant call to update on ActionController::Base#close_session [Andreas Schwarz] * Fixed that DRb Store accidently started its own server (instead of just client) [Andreas] * Fixed strip_links so it now works across multiple lines [Chad Fowler] * Fixed the TemplateError exception to show the proper trace on to_s (useful for unit test debugging) * Implemented class inheritable attributes without eval [Caio Chassot] * Made TextHelper#concat accept binding as it would otherwise not work * The FormOptionsHelper will now call to_s on the keys and values used to generate options
Markus Jais
2004-Oct-25 08:46 UTC
Re: [ANN] Rails 0.8: Just shy of 100 additions, changes, tweaks, and fixes!
wow, this is really impressive. I have not yet used or testet rails but mentioned it in my monthly Ruby News column for the german Linuxenterprise magazin. (just a few lines). I think rails really can be the killer app for ruby web programminng. thanks for all your work. I am looking forward to having more time and playing with rails. regards Markus --- David Heinemeier Hansson <david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org> schrieb:> It''s been fifty days since our last confession, so > it''s no wonder that > this outpouring is by far the biggest yet in Rails > history. It''s > absolutely packed with goodies ranging from a whole > new framework for > sending email to the smallest new alias for an > existing method. In > total we''re just shy of 100 additions, changes, > tweaks, and fixes. > > This is also the release with the highest number of > contributors. I''ve > counted at least 23 different people with patches in > Rails 0.8 -- and > there are many, many more responsible for > suggestions and bug reports. > This is truely turning into a community movement and > I''m extremely > pleased to be the steward for it. > > Get it all from http://www.rubyonrails.org, talk it > up on #rubyonrails > (FreeNet). > > Or even easier, just do "gem install rails" (or "gem > update" if you''re > already running on Gem Rails) -- you''ll > automatically install all the > newest versions of the required dependencies. (NOTE: > Wait 40 minutes > from this mail went out, so the gem repository is in > synch -- couldn''t > we check every 15 minutes instead of every hour :)?) > > Commercial announcement: If you''re looking for a > place to host your > Rails project or just to play around with it online, > we now have an > official hosting partner in TextDrive. I''m on board > to ensure that the > Rails experience is top notch and in return 50% of > the gross profits > are going to help further Rails. Read more on: > http://www.rubyonrails.org/show/TextDriveHosting > > > Rails 0.8.0: Multi-word classes are now welcome, > WEBrick binding >===============================================================>> * Removed custom_table_name option for new_model now > that the Inflector > is as powerful as it is > > * Changed the default rake action to just do testing > and separate API > generation and coding statistics into a "doc" task. > > * Fixed WEBrick dispatcher to handle missing slashes > in the URLs > gracefully [alexey] > > * Added user option for all postgresql tool calls in > the rakefile > [elvstone] > > * Fixed problem with running "ruby > public/dispatch.servlet" instead of > "cd public; ruby dispatch.servlet" [alexey] > > * Fixed WEBrick server so that it no longer > hardcodes the ruby > interpreter used to "ruby" but will get the one used > based on the Ruby > runtime configuration. [Marcel Molina Jr.] > > * Fixed Dispatcher so it''ll route requests to > magic_beans to > MagicBeansController/magic_beans_controller.rb [Caio > Chassot] > > * "new_controller MagicBeans" and "new_model > SubscriptionPayments" will > now both behave properly as they use the new > Inflector. > > * Fixed problem with MySQL foreign key constraint > checks in Rake > :clone_production_structure_to_test target [Andreas > Schwarz] > > * Changed WEBrick server to by default be > auto-reloading, which is > slower but makes source changes instant. Class > compilation cache can be > turned on with "-c" or "--cache-classes". > > * Added "-b/--binding" option to WEBrick dispatcher > to bind the server > to a specific IP address (default: 127.0.0.1) [Kevin > Temp] > > * dispatch.fcgi now DOESN''T set FCGI_PURE_RUBY as it > was slowing things > down for now reason [Andreas Schwarz] > > * Added new_mailer generator to work with Action > Mailer > > * Included new framework: Action Mailer 0.3 > > * Upgraded to Action Pack 0.9.0 > > * Upgraded to Active Record 1.0.0 > > > Action Mailer 0.3: Easy email delivery and testing > =================================================> > Action Mailer is framework for designing > email-service layers. These > layers are used to consolidate code for sending out > forgotten > passwords, welcoming wishes on signup, invoices for > billing, and any > other use case that requires a written notification > to either a person > or another system. > > The framework works by setting up all the email > details, except the > body, in methods on the service layer. Subject, > recipients, sender, and > timestamp are all set up this way. An example of > such a method: > > def signed_up(recipient) > @recipients = recipient > @subject = "[Signed up] Welcome > #{recipient}" > @from = "system-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org" > @sent_on = Time.local(2004, 12, 12) > > @body["recipient"] = recipient > end > > The body of the email is created by using an Action > View template > (regular ERb) that has the content of the @body hash > available as > instance variables. So the corresponding body > template for the method > above could look like this: > > Hello there, > > Mr. <%= @recipient %> > > And if the recipient was given as > "david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org", the email > generated would look like this: > > Date: Sun, 12 Dec 2004 00:00:00 +0100 > From: system-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org > To: david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org > Subject: [Signed up] Welcome > david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org > > Hello there, > > Mr. david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org > > You never actually call the instance methods like > signed_up directly. > Instead, you call class methods like deliver_* and > create_* that are > automatically created for each instance method. So > if the signed_up > method sat on ApplicationMailer, it would look like > this: > > >ApplicationMailer.create_signed_up("david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org")> # => > tmail object for testing > >ApplicationMailer.deliver_signed_up("david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org")> # sends > the email > >ApplicationMailer.new.signed_up("david-OiTZALl8rpK0mm7Ywyx6yg@public.gmane.org")> # won''t > work! > > > > Active Record 1.0.0: Easy email delivery and testing > ===================================================> > >=== message truncated === ___________________________________________________________ Gesendet von Yahoo! Mail - Jetzt mit 100MB Speicher kostenlos - Hier anmelden: http://mail.yahoo.de