Rails Refactoring to Resources: Using CRUD and REST in Your Rails Application

2 months ago
Full text

1. Ruby on rails (Electronic resource) 2. Object-oriented programming (Computer science) 3. Ruby (Computer pro- gram language) 4. Web site development . 5. Application softare--Development. I. Title

  This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission inany form or by any means, electronic, mechanical, photocopying, recording, or likewise. For information regarding permis- sions, write to: This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0or later (the latest version is presently available at http://www.opencontent.org/openpub/).

ISBN-13: 978-0-321-44561-9

  First printing November 2007 Parts of this book contain material excerpted from the Ruby and Rails source code and API documentation, Copyright ©2004-2006 by David Heinemeier Hansson under the MIT license. Chapter 18 contains material excerpted from the RSpec source code and API documentation, Copyright © 2005-2007 The RSpec Development Team.


Associate Publisher Copy EditorMark Taub Margaret BersonAcquisitions Editor ProofreaderDebra Williams Cauley Kathy RuizDevelopment Editor Technical Reviewer Francis Hwang Songlin QiuSebastian Delmont Managing EditorWilson Bilkovich Patrick KanouseCourtenay Gasking Sam Aaron Senior Project EditorNola Stowe San Dee PhillipsSusan Potter IndexerJon Larkowski Tim Wright Publishing CoordinatorCindy TeetersBook DesignerChuti PrasertsithCompositionMark Shirar This page intentionally left blank To Desi, my love, my companion, my muse. This page intentionally left blank This page intentionally left blank

Chapter 1 Rails Environments and Configuration

1 Startup 2 Default Environment Settings 2 Mode Override 2 Rails Gem Version 2 Bootstrapping 3RubyGems 5 Initializer 6Default Load Paths 6 Rails, Modules, and Auto-Loading Code 7Builtin Rails Info 8 Configuration 9 Skipping Frameworks 9 Additional Load Paths 10 Log-Level Override 10 ActiveRecord Session Store 10 Schema Dumper 11 Observers 11 Time Zones 11 Additional Configuration 13 Development Mode

14 Automatic Class Reloading 15

17 Production Mode

The Rails Class Loader 15Test Mode 17 Log File Analysis 22 Syslog 24Conclusion 25 Chapter 2 Working with Controllers 27 The Dispatcher: Where It All Begins

28 Request Handling

31 When in Doubt, Render 32

Getting Intimate with the Dispatcher 29Render unto View… Explicit Rendering 33 Rendering Another Action’s Template 33Rendering a Different Template Altogether 34 Rendering a Partial Template 35Rendering Inline Template Code 35 Rendering Text 35Rendering Other Types of Structured Data 36 : json36 :xml

36 Rendering Nothing

Rendering Options 37: content_type 37 :layout 37 :status 37 Redirecting 39 Controller/View Communication 42 Filters 43 Filter Inheritance 44Filter Types 46 Filter Classes 46 Inline Filter Method 47 Filter Chain Ordering 47Around Filters 48 Filter Conditions 50 Filter Chain Halting 50Streaming 51send_data(data, options = {}) 51 Options for send_data 52send_file(path, options = {}) 52 Options for send_file 55 Letting the Web Server Send Files 55 Conclusion 56 Chapter 3 Routing 57 The Two Purposes of Routing 58 Bound Parameters 60 Wildcard Components (“Receptors”) 61 Static Strings 62 The routes.rb File 63 The Default Route 65Spotlight on the :id Field 66 Default Route Generation 67Modifying the Default Route 68 The Ante-Default Route and respond_to 69respond_to and the HTTP-Accept Header 70 The Empty Route 71 Writing Custom Routes 72 Using Static Strings 72 Using Your Own “Receptors” 73 A Note on Route Order 75 Using Regular Expressions in Routes 76 Default Parameters and the url_for Method 76 What Happened to :id? 77 Using Literal URLs 79 Creating a Named Route 81 The Question of Using name_path Versus name_url 82Considerations 83 What to Name Your Routes

83 Argument Sugar 84

A Little More Sugar with Your Sugar? 85The Special Scope Method with_options 86 Conclusion 88 References 88 Chapter 4 REST, Resources, and Rails 89 REST in a Rather Small Nutshell 89 REST in Rails 91 Routing and CRUD 92 Resources and Representations 93 REST Resources and Rails 93From Named Routes to REST Support 94 Reenter the HTTP Verb 96 The Standard RESTful Controller Actions

96 The PUT and DELETE Cheat 98

  Singular and Plural RESTful Routes 98 The Special Pairs: new/create and edit/update 99Singular Resource Routes 100 Nested Resources 101 Setting :path_prefix Explicitly 103 Setting :name_prefix Explicitly 103Specifying RESTful Controllers Explicitly 105 All Together Now 105Considerations 107 Deep Nesting? and reconnect!

Chapter 7 ActiveRecord Associations 199 The Association Hierarchy 199 One-to-Many Relationships 201 Adding Associated Objects to a Collection 203 AssociationCollection Methods 204

<<(*records) and create(attributes = {}) 204 clear 205delete(*records) and delete_all 205 destroy_all 206length 206 replace(other_array) 206size 206 sum(column, *options) 206uniq 207 The belongs_to Association 207 Reloading the Association 208 Building and Creating Related Objects via the Association 208belongs_to Options 209 : class_name 209: conditions 210: foreign_key 213: counter_cache 213:i nclude 214: polymorphic => true 214 The has_many Association 215has_many Options 216 : after_add 216: after_remove 216: as 216: before_add 217: before_remove 217: class_name 218: conditions 218: counter_sql 218 : dependent => :delete_all 219: dependent => :destroy_all 219: dependent => :nullify 219: exclusively_dependent 219: extend => ExtensionModule 219: finder_sql 219: foreign_key 219: group 220:i nclude 220:i nsert_sql 223: limit 223 : offset 223: order 223: select 223: source and :source_type 223: table_name 223: through 224: uniq => true 224 Proxy Methods 224build(attributes = {}) 224 count(*args) 225find(*args) 225 Many-to-Many Relationships 225has_and_belongs_to_many 225 Self-Referential Relationship 226 Bidirectional Relationships 227Custom SQL Options 229 Extra Columns on has_and_belongs_to_many Join Tables 232 “Real Join Models” and habtm 232has_many :through 233 Join Models 233 Usage Considerations and Examples 235Aggregating Associations 236 Join Models and Validations 237 : source_type 238: uniq 240 One-to-One Relationships 241has_one 241 has_one Options 244 : as 244: class_name 244: conditions 245: dependent 245: foreign_key 245:i nclude 245: order 246 Unsaved Objects and Associations 246One-to-One Associations 246 Collections 247 Association Extensions 247 The AssociationProxy Class 249reload and reset 249 proxy_owner, proxy_reflection, and proxy_target 249 Conclusion 250 References 251

Chapter 8 ActiveRecord Validations 253 Finding Errors 253 The Simple Declarative Validations 254

validates_acceptance_of 254Error Message 255 The accept Option 255validates_associated 255 validates_confirmation_of 256validates_each 256 validates_inclusion_of and validates_exclusion_of 257validates_existence_of 257 validates_format_of 258 Constraint Options 260 Error Message Options 260validates_numericality_of 260 validates_presence_of 261 Validating the Presence of Associated Objects 261validates_uniqueness_of 261 Enforcing Uniqueness of Join Models 262RecordInvalid 263 Common Validation Options 263:allow_nil 263 :if 263:message 263 :on 264 Conditional Validation 264Usage and Considerations 265 Working with the Errors Object 266Manipulating the Errors Collection 267add_to_base(msg) 267 add(attribute, msg) 267clear 267 Checking for Errors 267i nvalid?(attribute) 267on(attribute) 267 Custom Validation 268 Skipping Validations 269 Conclusion 270Reference 270

Chapter 9 Advanced ActiveRecord 271 Callbacks 271 Callback Registration 272 One-Liners 273 Protected or Private 273 Matched before/after Callbacks 274

Callback Usages 275Cleaning Up Attribute Formatting with before_validate_on_create 275 Geocoding with before_save 275Paranoia with before_destroy 277 Cleaning Up Associated Files with after_destroy 277 Special Callbacks: after_initialize and after_find 278 Callback Classes 279Multiple Callback Methods in One Class 280 Testability 282 Observers 282Naming Conventions 283 Registration of Observers 283Timing 284 Single-Table Inheritance (STI) 284Mapping Inheritance to the Database 286 STI Considerations 288STI and Associations 288 Abstract Base Model Classes 291 Polymorphic has_many Relationships 292In the Case of Models with Comments 293 The Interface 293 The Database Columns 294Has_many :through and Polymorphics 295 Considerations about has_many 296Modules for Reusing Common Behavior 296 A Review of Class Scope and Contexts 299 The included Callback 300Modifying ActiveRecord Classes at Runtime 301 Considerations 303 Ruby and Domain-Specific Languages 303Conclusion 305 References 305

Chapter 10 ActionView 307


Commenting Out ERb Delimiters 310 Conditional Output 311 Layouts and Templates 312Yielding Content 313 Template Variables 315 Instance Variables 315 assigns 316base_path 316 controller 316flash 317 headers 318logger 318 params 319request and response 319 session 319 Protecting the Integrity of Your View from User-Submitted Content 319Partials 320 Simple Use Cases 321 Reuse of Partials 322Shared Partials 323 Passing Variables to Partials 324 The local_assigns Hash 325Render Collections 325 The partial_counter Variable 326 Sharing Collection Partials 326Logging 327 Caching 327Caching in Development Mode? 328 Page Caching 328Action Caching 328 Design Considerations 329Fragment Caching 330 The cache Method 330 Expiring Pages and Actions 333 Expiring Fragments 334Using regular expressions in expiration calls 334 Automatic Cache Expiry with Sweepers 335 Cache Logging 337Action Cache Plugin 337 Cache Storage 338 Configuration Example 339 Limitations of File-Based Storage 339Manual Sweeping with rake 339 Conclusion 340 References 340

Chapter 11 All About Helpers 341 ActiveRecordHelper 342 Reporting Validation Errors 342

error_message_on(object, method, prepend_text = “”, append_text = “”, css_class = “formError”) 342error_messages_for(*params) 343 Automatic Form Creation 344form(name, options) 344 input(name, method, options) 346 Customizing the Way Validation Errors Are Highlighted 346AssetTagHelper 348 Head Helpers 348auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {}) 348 image_path(source) 350 image_tag(source, options = {}) 350 javascript_include_tag(*sources) 351javascript_path(source) 352 stylesheet_link_tag(*sources) 352stylesheet_path(source) 352 For Plugins Only, Add Default JavaScript Includes 352 DateHelper 355The Date and Time Selection Helpers 355date_select(object_name, method, options = {}) 355 datetime_select(object_name, method, options = {}) 356time_select(object_name, method, options = {}) 356 The Individual Date and Time Select Helpers 356select_date(date = Date.today, options = {}) 357 select_datetime(datetime = Time.now, options = {}) 357select_day(date, options = {}) 357 select_hour(datetime, options = {}) 357select_minute(datetime, options = {}) 357 select_month(date, options = {}) 358select_second(datetime, options = {}) 358 select_time(datetime, options = {}) 358select_year(date, options = {}) 359 Common Options for Date Selection Helpers 359 distance_in_time Methods with Complex Descriptive Names 359distance_of_time_in_words(from_time, to_time = 0, include_seconds = false) 360 distance_of_time_in_words_to_now(from_time, include_seconds = false) 361 DebugHelper 361 FormHelper 362Creating Forms for ActiveRecord Models 362 Variables Are Optional 363 Rails-Generated Form Conventions 363Displaying Existing Values 364 Updating Multiple Objects at Once 364Square Brackets with New Records? 365 Indexed Input Fields 366 Select Helpers 371collection_select(object, attribute, collection, value_method, text_method, options = {}, html_options = {}) 372country_select(object, attribute, priority_countries = nil, options = {}, html_options = {}) 372select(object, attribute, choices, options = {}, html_options = {}) 372 time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) 373 Option Helpers 373country_options_for_select(selected = nil, priority_countries = nil) 373 option_groups_from_collection_for_select(collection, group_method, group_label_method,option_key_method, option_value_method, selected_key = nil) 373 options_for_select(container, selected = nil) 375options_from_collection_for_select(collection, value_method, text_method, selected=nil) 377time_zone_options_for_select(selected = nil, priority_ zones = nil, model = TimeZone) 377 FormTagHelper 378check_box_tag(name, value = “1”, checked = false, options = {}) 378 end_form_tag 378file_field_tag(name, options = {}) 378 form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block) 379hidden_field_tag(name, value = nil, options = {}) 380 image_submit_tag(source, options = {}) 380 password_field_tag(name = “password”, value = nil, options = {}) 380radio_button_tag(name, value, checked = false, options = {}) 380 select_tag(name, option_tags = nil, options = {}) 380start_form_tag 380 submit_tag(value = “Save changes”, options = {}) 381text_area_tag(name, content = nil, options = {}) 381 text_field_tag(name, value = nil, options = {}) 381 JavaScriptHelper 381 button_to_function(name, function, html_options={}, &block) 381define_javascript_functions() 382 escape_javascript(javascript) 382javascript_tag(content, html_options={}) 382 link_to_function(name, function, html_options={}, &block) 382 RecordIdentificationHelper 388 dom_class(record_or_class, prefix = nil) 389dom_id(record, prefix = nil) 389 partial_path(record_or_class) 389 RecordTagHelper 390 content_tag_for(tag_name, record, *args, &block) 390div_for(record, *args, &block) 391 TagHelper 391cdata_section(content) 391 content_tag(name, content = nil, options = nil, &block) 391escape_once(html) 392 tag(name, options = nil, open = false) 392 TextHelper 393 auto_link(text, link = :all, href_options = {}, &block) 393concat(string, binding) 393 cycle(first_value, *values) 394excerpt(text, phrase, radius = 100, excerpt_string = “...”) 395 highlight(text, phrases, highlighter = ‘<strong class=”highlight”>\1</strong>’) 395markdown(text) 396 pluralize(count, singular, plural = nil) 396reset_cycle(name = “default”) 397 sanitize(html) 397simple_format(text) 398 strip_links(text) 398strip_tags(html) 398 Writing Your Own Helpers 407Small Optimizations: The Title Helper 407 Encapsulating View Logic: The photo_for Helper 408Smart View: The breadcrumbs Helper 409 Wrapping and Generalizing Partials 410A tiles Helper 410 Explanation of the Tiles Partial Code 411 Calling the Tiles Partial Code 412Write the Helper Method 413 Generalizing Partials 414Lambda: the Ultimate 414 The New Tiled Helper Method 415 Conclusion 417 References 417

Chapter 12 Ajax on Rails 419 Prototype 420 FireBug 421 The Prototype API 421 Top-Level Functions 422

  Responders.register(responder) 437 Ajax. 542 parts 542subject 542 to 542 Handling Attachments 543Configuration 543 Conclusion 544References 544 Rails Mocks?

Chapter 18 RSpec on Rails 597 Introduction to RSpec 597 Should and Expectations 598 Predicates 599 Custom Expectation Matchers 601 Multiple Examples per Behavior 603 Shared Behaviors 604 RSpec’s Mocks and Stubs 607 Mock Objects 607 Null Objects 608 Stub Objects 608

Generators 614 Model Specs 614Controller Specs 617 Isolation and Integration Modes 619 Specifying Errors 620Specifying Routes 620 View Specs 621Assigning Instance Variables 622 Stubbing Helper Methods 623 Helper Specs 623 Scaffolding 623RSpec Tools 624 Autotest 624 RCov 624Conclusion 625 References 626

Chapter 19 Extending Rails with Plugins 627 Managing Plugins 628 Reusing Code 628 The Plugin Script 629

script/plugin list 629 script/plugin sources 630script/plugin source [url [url2 [...]]] 630 script/plugin unsource [url[url2 [...]]] 631script/plugin discover [url] 631 script/plugin install [plugin] 632script/plugin remove [plugin] 633 script/plugin update [plugin] 633 Subversion and script/plugin 633Checking Out a Plugin 634 script/plugin update 634SVN Externals 635 Locking Down a Specific Version 636 Converting Existing Vendor Libraries 638 Updating 638Locking and Unlocking Revisions 639 Piston Properties 639 Writing Your Own Plugins 640The init.rb Hook 640 The lib Directory 642Extending Rails Classes 643 The README and MIT-LICENSE File 644The install.rb and uninstall.rb Files 645 Installation 645 Removal 646Common Sense Reminder 646 Custom Rake Tasks 647 The Plugin’s Rakefile 648Testing Plugins 649 Conclusion 649 References 650

Chapter 20 Rails Production Configurations 651 A Brief History of Rails In Production 652 Some Basic Prerequisites 652 The Stack Checklist 654 Server and Network Environment 655 Standalone/Dedicated Server or VPS Slice 655 Fresh OS Install 655 Network Access 655 Web Tier 656 Application Tier 656 Database Tier 656 Monitoring 657 Version Control 657 Installations 657 Ruby 658

Mongrel Cluster 659 Nginx 659Subversion 660 MySQL 660Monit 661 Capistrano 661 Configurations 661Configuring Mongrel Cluster 662 Configuring Nginx 663nginx.conf 663 railsway.conf 664 Configuring Monit 667 Configuring Capistrano 670Configuring init Scripts 670 Nginx init Script 670 Mongrel init Script 672Monit Configuration 673 Deployment and Launch 675 Other Production Stack Considerations 675Redundancy and Failover 676 Caching 676Performance and Scalability 676 Security 677 Application Security 677 Lock Down Your Ports 678Maintainability 678 Conclusion 678 References 679

Chapter 21 Capistrano 681 Overview of Capistrano 681 Terminology 682 The Basics 682 What Do I Need to Do to Use Capistrano? 682

  691Overriding Capistrano Assumptions 691 Using a Remote User Account 691 Customizing the SCM System Used by Capistrano 692Working without SCM Access from the Deployment Machine 692 What If I Don’t Store database.yml in My SCM Repository? 693 Option A: Version It Anyway, but with a Different Name 693 Option B: Store Production-Ready database.yml in the shared/config Folder 694Option C: The Best Option: Autogenerate database.yml 694 What If My Migrations Won’t Run from 0 to 100?

Chapter 22 Background Processing 707

  On the contrary, it trades that flexibility for the convenience of “what most people need most of the time to do most things.” It’s a designer straightjacket thatsets you free from focusing on the things that just don't matter and focuses your attention on the stuff that does. Therefore, the flow of the book is as follows: ActiveRecordbasics, associations, validation, and advanced techniques templating, caching, and helpers ActiveResource ActionMailer Following in the footsteps of my series colleague Hal Fulton and The Ruby Way, most of the snippets are not full code listings—only the relevant code is shown.

1 Rails Environments and

  It is commented out, since it should be unusual to need to set the Rails modehere: # Uncomment below to force Rails into production mode when # you don’t control web/app server and can’t set it the proper way# ENV[‘RAILS_ENV’] ||= ‘production’ A word of caution: If you were to set the environment variable to production RAILS_ENV here, or the constant variable for that matter, it would cause everything you did in Rails to run in production mode. Rails Environments and ConfigurationAdditional Load Paths In the rare case of needing to add to the default load paths, the option is given to do so next: # Add additional load paths for your own custom dirs config.load_paths += %W( #{RAILS_ROOT}/extras )%W In case you didn’t know, the functions as a whitespace-delimited array literal and is used quite often in the Rails codebase for convenience.

2 Working with Controllers

  Here’s the command: >> Dispatcher.dispatch And here’s the response from the Rails application: Content-Type: text/html; charset=utf-8 Set-Cookie: _dispatch_me_session_id=336c1302296ab4fa1b0d838d; path=/Status: 200 OK We’ve executed the class method of the Ruby class , and index as a result, the action got executed and the index template (such as it is) got rendered and the results of the rendering got wrapped in some HTTP headers andreturned. Let’s go back to this version of the demo controller: class DemoController < ApplicationController def indexend end What you learn from seeing the empty action is that, at the end of every controller if nothing else is specified, the default behavior is to render the template whose action, app/ name matches the name of the controller and action.

3 Routing I dreamed a thousand new paths. . . I woke and walked my old one

  What happens is that the route generator marches along the template segments, from left to right—in the default case like this: And it fills in the fields based on the parameters from the current request until it hits one where you’ve provided a value: “edit” i s no longer to the right of :action , but to its left, the gen- erator would happily fill in both :controller and :id from their values in the cur- rent request. Rails way to use _path _url nstead of It produces a shorter string and the user agent(browser or otherwise) should be able to infer the fully qualified URL whenever it needs to do so, based on the HTTP headers of the request, a base element in the doc-ument, or the URL of the request.

4 REST, Resources, and Rails

  In the large scheme of things, the benefits that accrue to you when you useRails’ REST support fall into two categories: Convenience and automatic best practices for you This isn’t meant to minimize the importance of REST itself, nor the seriousness of the endeavor of providing REST-based services. Again, the focus will be on showing you how the REST support works, and opening the door to fur-ther study and practice—including the study of Fielding’s dissertation and the theo- retical tenets of REST.

Dokumen baru

Aktifitas terbaru

Download (910 Halaman)


Mike Clark And The Rails Community Jrub Y On Rails Foundation Rails 2 X Pdf Agile Web Development With Rails Rolling With Ruby On Rails Part 374 Head First Rails Free Download Ebook Agile Web Development With Rails 5 1 Pdf Pdf Using Your Body To Strengthen Your Mind Using Your Thinking Cap In How To Save Money
Show more