Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Update model topics to 1.9-hash syntax per #313.

  • Loading branch information...
commit 847e64fc8424620d549e1b3957da0c3720066985 1 parent a1d6a4a
@kytrinyx kytrinyx authored
View
4 source/topics/models/legacy_databases.markdown
@@ -113,7 +113,7 @@ And what about relationships? Imagine there is an associated `Order` object wher
class Customer < ActiveRecord::Base
set_table_name 'existing_customers'
set_primary_key 'customer_id'
- has_many :orders, :foreign_key => 'existing_customer_id'
+ has_many :orders, foreign_key: 'existing_customer_id'
end
```
@@ -121,7 +121,7 @@ That is the `foreign_key` within the `orders` table pointing back to this `Custo
```ruby
class Order < ActiveRecord::Base
- belongs_to :customer, :foreign_key => 'existing_customer_id'
+ belongs_to :customer, foreign_key: 'existing_customer_id'
end
```
View
18 source/topics/models/modules.markdown
@@ -269,12 +269,12 @@ We can use `included` to share more than method definitions. Imagine that both `
```ruby
class Article < ActiveRecord::Base
include TextContent
- has_one :moderator_approval, :as => :content
+ has_one :moderator_approval, as: :content
end
class Comment < ActiveRecord::Base
include TextContent
- has_one :moderator_approval, :as => :content
+ has_one :moderator_approval, as: :content
end
```
@@ -287,7 +287,7 @@ Your first instinct might be to try this:
```ruby
module TextContent
#...
- has_one :moderator_approval, :as => :content
+ has_one :moderator_approval, as: :content
end
```
@@ -303,7 +303,7 @@ module TextContent
def self.included(including_class)
including_class.extend ClassMethods
- including_class.send(:has_one, :moderator_approval, {:as => :content})
+ including_class.send(:has_one, :moderator_approval, {as: :content})
end
end
```
@@ -325,7 +325,7 @@ module TextContent
def self.included(including_class)
including_class.class_eval do
extend ClassMethods
- has_one :moderator_approval, :as => :content
+ has_one :moderator_approval, as: :content
end
end
end
@@ -361,7 +361,7 @@ module TextContent
extend ActiveSupport::Concern
included do
extend ClassMethods
- has_one :moderator_approval, :as => :content
+ has_one :moderator_approval, as: :content
end
#...
end
@@ -377,7 +377,7 @@ If our module follows the pattern of defining class methods in an interior modul
module TextContent
extend ActiveSupport::Concern
included do
- has_one :moderator_approval, :as => :content
+ has_one :moderator_approval, as: :content
end
#...
end
@@ -404,7 +404,7 @@ module TextContent
end
included do
- has_one :moderator_approval, :as => :content
+ has_one :moderator_approval, as: :content
end
end
```
@@ -429,4 +429,4 @@ end
2. Include the module into both `Comment` and `Article` models.
3. Pull the related tests out of `article_spec.rb` and `comment_spec.rb`, write a `text_content_spec.rb`, and relocate the tests. Now that you've ensured the functionality of the methods, from the `article_spec.rb` and `comment_spec.rb` you can just check that the class and instances respond to the proper methods.
4. Define a second module named `Commentable` that, for starters, just causes the including class to run `has_many :comments`. Remove the `has_many` from `Article` and, instead, include the module. Imagine that, in the future, we'd have a `Photo` object which also accepted comments.
-5. Define an instance method in the `Commentable` module named `has_comments?` which returns true or false based on the existence of comments. In the `articles#show` view, use that method to show or hide the comments display based on their existence.
View
6 source/topics/models/polymorphism.markdown
@@ -59,7 +59,7 @@ But that *won't work* because Rails will expect to find a `person_id` column in
```ruby
class Person < ActiveRecord::Base
- has_one :phone_number, :as => :contact
+ has_one :phone_number, as: :contact
end
```
@@ -69,7 +69,7 @@ In `PhoneNumber`, we tell it about the relationship to contacts:
```ruby
class PhoneNumber < ActiveRecord::Base
- belongs_to :contact, :polymorphic => true
+ belongs_to :contact, polymorphic: true
end
```
@@ -93,7 +93,7 @@ But what about when a `Person` or `Company` relates to many `PhoneNumber` object
```ruby
class Person < ActiveRecord::Base
- has_many :phone_numbers, :as => :contact
+ has_many :phone_numbers, as: :contact
end
```
View
12 source/topics/models/processor_models.markdown
@@ -108,7 +108,7 @@ If you have multiple child objects with many methods, writing and maintaining th
```ruby
class MyObject
attr_reader :child
- delegate :the_method, :to => child
+ delegate :the_method, to: child
end
```
@@ -117,7 +117,7 @@ This has the exact same effect as the wrapper above. You can delegate many metho
```ruby
class MyObject
attr_reader :child
- delegate :the_method, :second_method, :third_method, :to => child
+ delegate :the_method, :second_method, :third_method, to: child
end
```
@@ -151,9 +151,9 @@ From there we could expose child attributes:
```ruby
class StudentReport
attr_reader :student, :term, :report_type
- delegate :first_name, :last_name, :to => :student
- delegate :title, :subtitle, :to => :report_type
- delegate :start_date, :end_date, :to => :term
+ delegate :first_name, :last_name, to: :student
+ delegate :title, :subtitle, to: :report_type
+ delegate :start_date, :end_date, to: :term
end
```
@@ -184,4 +184,4 @@ We have both `Article` and `Comment` models. Let's imagine that we want to start
2. Implement a `word_count` method that calculates the total word count of the article and all comments.
3. Proxy the `title` method so when it is called on an instance of `Thread` it returns the title of the article.
4. Create a `commentors` method that fetches all the comment authors.
-5. Create a `last_updated` method that returns the most recent change to the thread, either a change to the article or to a comment.
View
24 source/topics/models/relationships.markdown
@@ -107,7 +107,7 @@ Now when we call `Customer.new` it will automatically build a `Detail` and assoc
Given the current setup, when we destroy a `Customer` it is going to leave an orphaned `Detail` object in the database. Instead, we want the child object destroyed automatically when the parent is destroyed. That's accomplished with this change to the `has_one`:
```ruby
-has_one :detail, :dependent => :destroy
+has_one :detail, dependent: :destroy
```
#### Hiding the Child Object
@@ -118,9 +118,9 @@ To do that we use Rails' `delegate` method:
```ruby
class Customer < ActiveRecord::Base
- has_one :detail, :dependent => :destroy
+ has_one :detail, dependent: :destroy
- delegate :birthday, :gender, :city, :to => :detail
+ delegate :birthday, :gender, :city, to: :detail
after_initialize do
self.build_detail
@@ -135,7 +135,7 @@ Then when we call `Customer.find(17).city` it will proxy the call to the associa
One small catch here is that `delegate` only handles the listed methods, so if you want to have full read/write access to the child's attributes you'd need:
```ruby
-delegate :birthday, :birthday=, :gender, :gender=, :city, :city=, :to => :detail
+delegate :birthday, :birthday=, :gender, :gender=, :city, :city=, to: :detail
```
The list starts to get long, and if we add methods to `Detail` we need to remember to add them to the delegation. Programmers don't remember things, so here's one solution:
@@ -148,9 +148,9 @@ class Detail < ActiveRecord::Base
end
class Customer < ActiveRecord::Base
- has_one :detail, :dependent => :destroy
+ has_one :detail, dependent: :destroy
- delegate *Detail::ATTR_METHODS, :to => :detail
+ delegate *Detail::ATTR_METHODS, to: :detail
after_initialize do
self.build_detail
@@ -188,8 +188,8 @@ The `has_many :orders` tells Rails to expect a model named `Order` that has a fo
When you create a `Customer` it won't have any child `Order` objects. Here are three ways to create one, assuming we have a `customer` object:
-* `Order.new(:customer_id => customer.id)` -- least preferred. It has no future flexibility if we change details like the foreign key name
-* `Order.new(:customer => customer)` -- better. It created the object through the `ActiveRecord` relationship, so we can handle the details in that relationship.
+* `Order.new(customer_id: customer.id)` -- least preferred. It has no future flexibility if we change details like the foreign key name
+* `Order.new(customer: customer)` -- better. It created the object through the `ActiveRecord` relationship, so we can handle the details in that relationship.
* `customer.orders.new` -- best. The order is built directly off the relationship, hiding all the details. We can add things like a validation on customer that they don't have more than X open orders or whatever else applies to our domain. Note that `customer.orders.build` is equivalent to calling `.new`.
#### Destroying Children
@@ -198,7 +198,7 @@ Just like the `has_one` relationship, we frequently want the child objects to be
```ruby
class Customer < ActiveRecord::Base
- has_many :orders, :dependent => :destroy
+ has_many :orders, dependent: :destroy
end
```
@@ -274,12 +274,12 @@ The solution is to add a second relationship to each of the primary models:
```ruby
class Magazine < ActiveRecord::Base
has_many :subscriptions
- has_many :customers, :through => :subscriptions
+ has_many :customers, through: :subscriptions
end
class Customer < ActiveRecord::Base
has_many :subscriptions
- has_many :magazines, :through => :subscriptions
+ has_many :magazines, through: :subscriptions
end
```
@@ -287,4 +287,4 @@ Using "has many through", Rails can hop across the intermediary relationship. We
## Reference
-* Ruby's splat operator: http://kconrails.com/2010/12/22/rubys-splat-operator/
View
54 source/topics/models/validations.markdown
@@ -12,7 +12,7 @@ Before we begin, let's talk about syntax. There are two primary syntaxes for wri
```ruby
validates_presence_of :price
-validates :price, :presence => true
+validates :price, presence: true
```
These have the exact same functionality. The first is the older style and the second a newer "Rails 3 style". The Rails 3 style shines when we add in a second validation on the same field:
@@ -23,7 +23,7 @@ validates_presence_of :price
validates_numericality_of :price
# Rails 3 Style
-validates :price, :presence => true, :numericality => true
+validates :price, presence: true, numericality: true
```
The newer syntax allows you to condense multiple validations into a single line of code.
@@ -84,9 +84,9 @@ We can add a few options to add criteria to our "numbers":
* `:only_integer` will only accept integers
- ```ruby
- validates_numericality_of :price, :only_integer => true
- ```
+```ruby
+validates_numericality_of :price, only_integer: true
+```
* Control the range of values with these options:
* `:greater_than`
@@ -95,11 +95,11 @@ We can add a few options to add criteria to our "numbers":
* `:less_than_or_equal_to`
For example:
- ```ruby
- validates_numericality_of :price, :greater_than => 0
- validates_numericality_of :price, :less_than => 1000
- validates_numericality_of :price, :greater_than => 0, :less_than => 1000
- ```
+```ruby
+validates_numericality_of :price, greater_than: 0
+validates_numericality_of :price, less_than: 1000
+validates_numericality_of :price, greater_than: 0, less_than: 1000
+```
### Length
@@ -112,10 +112,10 @@ Check the length of a string with `validates_length_of`.
`validates_length_of` obviously needs to know what the length should be. Here are a few examples of the common specifiers:
```ruby
-validates_length_of :zipcode, :is => 5
-validates_length_of :title, :minimum => "10"
-validates_length_of :title, :maximum => "1000"
-validates_length_of :title, :in => (10..1000)
+validates_length_of :zipcode, is: 5
+validates_length_of :title, minimum: "10"
+validates_length_of :title, maximum: "1000"
+validates_length_of :title, in: (10..1000)
```
### Format
@@ -135,13 +135,13 @@ The `validates_format_of` method is the Swiss Army knife of validations. It atte
The canonical example is email address format validation:
```ruby
-validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
+validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
```
Or reject based on a regex using the `:without` option:
```ruby
-validates_format_of :comment, :without => /(<script>|<\/script>)/
+validates_format_of :comment, without: /(<script>|<\/script>)/
```
### Inclusion
@@ -153,7 +153,7 @@ Check that a value is in a given set with `validates_inclusion_of`.
#### Usage
```ruby
-validates_inclusion_of :birth_year, :in => (1880..2011)
+validates_inclusion_of :birth_year, in: (1880..2011)
```
The `:in` parameter will accept a Ruby range like this example or any other `Enumerable` object (like an `Array`).
@@ -203,7 +203,7 @@ Calling the `valid?` method on an instance will run the validations and return `
```irb
ruby-1.9.2-p290 :003 > p.errors
- => {:title=>["can't be blank"]}
+ => {title:["can't be blank"]}
ruby-1.9.2-p290 :004 > p.errors.full_messages
=> ["Title can't be blank"]
```
@@ -231,9 +231,9 @@ A call to `save` will return `true` if the save succeeds and `false` if it fails
def create
@product = Product.new(params[:product])
if @product.save
- redirect_to @product, :notice => "Successfully created product."
+ redirect_to @product, notice: "Successfully created product."
else
- render :action => 'new'
+ render action: 'new'
end
end
```
@@ -278,11 +278,11 @@ But now we can write our own `error_messages_for`, imitate Rails 2, and leave th
```ruby
def error_messages_for(*objects)
options = objects.extract_options!
- options[:header_message] ||= I18n.t(:"activerecord.errors.header", :default => "Invalid Fields")
- options[:message] ||= I18n.t(:"activerecord.errors.message", :default => "Correct the following errors and try again.")
+ options[:header_message] ||= I18n.t(:"activerecord.errors.header", default: "Invalid Fields")
+ options[:message] ||= I18n.t(:"activerecord.errors.message", default: "Correct the following errors and try again.")
messages = objects.compact.map { |o| o.errors.full_messages }.flatten
unless messages.empty?
- content_tag(:div, :class => "error_messages") do
+ content_tag(:div, class: "error_messages") do
list_items = messages.map { |msg| content_tag(:li, msg) }
content_tag(:h2, options[:header_message]) + content_tag(:p, options[:message]) + content_tag(:ul, list_items.join.html_safe)
end
@@ -334,10 +334,10 @@ For truly bullet-proof data integrity you'll need to implement validations at th
* The `foreigner` gem gives you the ability to add foreign key constraints to MySQL, PostgreSQL, and SQLite: https://github.com/matthuhiggins/foreigner
* `validates_uniqueness_of` could, in theory, run into a race condition if there are two concurrent requests creating the same data. To protect against that, you can create a database index on the field and specify that it must be unique:
- ```ruby
- # in your migration...
- t.index(:title, :unique => true)
- ```
+```ruby
+# in your migration...
+t.index(:title, unique: true)
+```
Then the database would reject a second submission with an existing title if it got past the Rails model validation
Please sign in to comment.
Something went wrong with that request. Please try again.