View
@@ -84,7 +84,7 @@ def through_scope
end
scope.references! reflection_scope.values[:references]
scope.order! reflection_scope.values[:order] if scope.eager_loading?
scope = scope.order reflection_scope.values[:order] if scope.eager_loading?
end
scope
View
@@ -14,9 +14,11 @@ module ThroughAssociation #:nodoc:
def target_scope
scope = super
chain.drop(1).each do |reflection|
relation = reflection.klass.all
relation.merge!(reflection.scope) if reflection.scope
scope.merge!(
reflection.klass.all.
except(:select, :create_with, :includes, :preload, :joins, :eager_load)
relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load)
)
end
scope
View
@@ -296,7 +296,6 @@ class Base
include Core
include Persistence
include NoTouching
include ReadonlyAttributes
include ModelSchema
include Inheritance
@@ -318,6 +317,7 @@ class Base
include NestedAttributes
include Aggregations
include Transactions
include NoTouching
include Reflection
include Serialization
include Store
View
@@ -209,12 +209,7 @@ def type_cast(value)
class Timestamp < Type
def type; :timestamp; end
def simplified_type(sql_type)
case sql_type
when /^timestamp with(?:out)? time zone$/
:datetime
else
:timestamp
end
:datetime
end
def type_cast(value)
View
@@ -40,7 +40,7 @@ def inherited(child_class)
BLACKLISTED_ARRAY_METHODS = [
:compact!, :flatten!, :reject!, :reverse!, :rotate!, :map!,
:shuffle!, :slice!, :sort!, :sort_by!, :delete_if,
:keep_if, :pop, :shift, :delete_at, :compact
:keep_if, :pop, :shift, :delete_at, :compact, :select!
].to_set # :nodoc:
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, to: :to_a
View
@@ -242,7 +242,7 @@ def fifth!
# If no order is defined it will order by primary key.
#
# Person.forty_two # returns the forty-second object fetched by SELECT * FROM people
# Person.offset(3).forty_two # returns the fifth object from OFFSET 3 (which is OFFSET 44)
# Person.offset(3).forty_two # returns the forty-second object from OFFSET 3 (which is OFFSET 44)
# Person.where(["user_name = :u", { u: user_name }]).forty_two
def forty_two
find_nth(41, offset_index)
View
@@ -30,6 +30,8 @@ def other
else
other.joins!(*v)
end
elsif k == :select
other._select!(v)
else
other.send("#{k}!", v)
end
@@ -62,7 +64,13 @@ def merge
# expensive), most of the time the value is going to be `nil` or `.blank?`, the only catch is that
# `false.blank?` returns `true`, so there needs to be an extra check so that explicit `false` values
# don't fall through the cracks.
relation.send("#{name}!", *value) unless value.nil? || (value.blank? && false != value)
unless value.nil? || (value.blank? && false != value)
if name == :select
relation._select!(*value)
else
relation.send("#{name}!", *value)
end
end
end
merge_multi_values
View
@@ -64,6 +64,7 @@ def #{name}_values # def select_values
#
def #{name}_values=(values) # def select_values=(values)
raise ImmutableRelation if @loaded # raise ImmutableRelation if @loaded
check_cached_relation
@values[:#{name}] = values # @values[:select] = values
end # end
CODE
@@ -81,11 +82,22 @@ def #{name}_value # def readonly_value
class_eval <<-CODE, __FILE__, __LINE__ + 1
def #{name}_value=(value) # def readonly_value=(value)
raise ImmutableRelation if @loaded # raise ImmutableRelation if @loaded
check_cached_relation
@values[:#{name}] = value # @values[:readonly] = value
end # end
CODE
end
def check_cached_relation # :nodoc:
if defined?(@arel) && @arel
@arel = nil
ActiveSupport::Deprecation.warn <<-WARNING
Modifying already cached Relation. The cache will be reset.
Use a cloned Relation to prevent this warning.
WARNING
end
end
def create_with_value # :nodoc:
@values[:create_with] || {}
end
@@ -235,11 +247,11 @@ def select(*fields)
to_a.select { |*block_args| yield(*block_args) }
else
raise ArgumentError, 'Call this with at least one field' if fields.empty?
spawn.select!(*fields)
spawn._select!(*fields)
end
end
def select!(*fields) # :nodoc:
def _select!(*fields) # :nodoc:
fields.flatten!
fields.map! do |field|
klass.attribute_alias?(field) ? klass.attribute_alias(field) : field
View
@@ -1082,7 +1082,7 @@ def test_has_many_through_obeys_order_on_through_association
assert_equal ["parrot", "bulbul"], owner.toys.map { |r| r.pet.name }
end
test "has many through associations on new records use null relations" do
def test_has_many_through_associations_on_new_records_use_null_relations
person = Person.new
assert_no_queries do
@@ -1094,19 +1094,19 @@ def test_has_many_through_obeys_order_on_through_association
end
end
test "has many through with default scope on the target" do
def test_has_many_through_with_default_scope_on_the_target
person = people(:michael)
assert_equal [posts(:thinking)], person.first_posts
readers(:michael_authorless).update(first_post_id: 1)
assert_equal [posts(:thinking)], person.reload.first_posts
end
test "has many through with includes in through association scope" do
def test_has_many_through_with_includes_in_through_association_scope
assert_not_empty posts(:welcome).author_address_extra_with_address
end
test "insert records via has_many_through association with scope" do
def test_insert_records_via_has_many_through_association_with_scope
club = Club.create!
member = Member.create!
Membership.create!(club: club, member: member)
@@ -1117,4 +1117,16 @@ def test_has_many_through_obeys_order_on_through_association
club.reload
assert_equal [member], club.favourites
end
def test_has_many_through_unscope_default_scope
post = Post.create!(:title => 'Beaches', :body => "I like beaches!")
Reader.create! :person => people(:david), :post => post
LazyReader.create! :person => people(:susan), :post => post
assert_equal 2, post.people.to_a.size
assert_equal 1, post.lazy_people.to_a.size
assert_equal 2, post.lazy_readers_unscope_skimmers.to_a.size
assert_equal 2, post.lazy_people_unscope_skimmers.to_a.size
end
end
View

This file was deleted.

Oops, something went wrong.
View
@@ -0,0 +1,54 @@
require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class AdapterLeasingTest < ActiveRecord::TestCase
class Pool < ConnectionPool
def insert_connection_for_test!(c)
synchronize do
@connections << c
@available.add c
end
end
end
def setup
@adapter = AbstractAdapter.new nil, nil
end
def test_in_use?
assert_not @adapter.in_use?, 'adapter is not in use'
assert @adapter.lease, 'lease adapter'
assert @adapter.in_use?, 'adapter is in use'
end
def test_lease_twice
assert @adapter.lease, 'should lease adapter'
assert_not @adapter.lease, 'should not lease adapter'
end
def test_expire_mutates_in_use
assert @adapter.lease, 'lease adapter'
assert @adapter.in_use?, 'adapter is in use'
@adapter.expire
assert_not @adapter.in_use?, 'adapter is in use'
end
def test_close
pool = Pool.new(ConnectionSpecification.new({}, nil))
pool.insert_connection_for_test! @adapter
@adapter.pool = pool
# Make sure the pool marks the connection in use
assert_equal @adapter, pool.connection
assert @adapter.in_use?
# Close should put the adapter back in the pool
@adapter.close
assert_not @adapter.in_use?
assert_equal @adapter, pool.connection
end
end
end
end
View
@@ -2,199 +2,6 @@
module ActiveRecord
module ConnectionAdapters
class MergeAndResolveDefaultUrlConfigTest < ActiveRecord::TestCase
def klass
ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig
end
def setup
@previous_database_url = ENV.delete("DATABASE_URL")
end
teardown do
ENV["DATABASE_URL"] = @previous_database_url
end
def resolve(spec, config)
ConnectionSpecification::Resolver.new(klass.new(config).resolve).resolve(spec)
end
def spec(spec, config)
ConnectionSpecification::Resolver.new(klass.new(config).resolve).spec(spec)
end
def test_resolver_with_database_uri_and_current_env_symbol_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = resolve(:default_env, config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_resolver_with_database_uri_and_and_current_env_string_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = assert_deprecated { resolve("default_env", config) }
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_resolver_with_database_uri_and_known_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
actual = resolve(:production, config)
expected = { "adapter"=>"not_postgres", "database"=>"not_foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_resolver_with_database_uri_and_unknown_symbol_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
assert_raises AdapterNotSpecified do
resolve(:production, config)
end
end
def test_resolver_with_database_uri_and_unknown_string_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
assert_deprecated do
assert_raises AdapterNotSpecified do
spec("production", config)
end
end
end
def test_resolver_with_database_uri_and_supplied_url
ENV['DATABASE_URL'] = "not-postgres://not-localhost/not_foo"
config = { "production" => { "adapter" => "also_not_postgres", "database" => "also_not_foo" } }
actual = resolve("postgres://localhost/foo", config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_jdbc_url
config = { "production" => { "url" => "jdbc:postgres://localhost/foo" } }
actual = klass.new(config).resolve
assert_equal config, actual
end
def test_environment_does_not_exist_in_config_url_does_exist
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = klass.new(config).resolve
expect_prod = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expect_prod, actual["default_env"]
end
def test_url_with_hyphenated_scheme
ENV['DATABASE_URL'] = "ibm-db://localhost/foo"
config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
actual = resolve(:default_env, config)
expected = { "adapter"=>"ibm_db", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_string_connection
config = { "default_env" => "postgres://localhost/foo" }
actual = klass.new(config).resolve
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
}
}
assert_equal expected, actual
end
def test_url_sub_key
config = { "default_env" => { "url" => "postgres://localhost/foo" } }
actual = klass.new(config).resolve
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
}
}
assert_equal expected, actual
end
def test_hash
config = { "production" => { "adapter" => "postgres", "database" => "foo" } }
actual = klass.new(config).resolve
assert_equal config, actual
end
def test_blank
config = {}
actual = klass.new(config).resolve
assert_equal config, actual
end
def test_blank_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = {}
actual = klass.new(config).resolve
expected = { "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost" }
assert_equal expected, actual["default_env"]
assert_equal nil, actual["production"]
assert_equal nil, actual["development"]
assert_equal nil, actual["test"]
assert_equal nil, actual[:production]
assert_equal nil, actual[:development]
assert_equal nil, actual[:test]
end
def test_url_sub_key_with_database_url
ENV['DATABASE_URL'] = "NOT-POSTGRES://localhost/NOT_FOO"
config = { "default_env" => { "url" => "postgres://localhost/foo" } }
actual = klass.new(config).resolve
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
}
}
assert_equal expected, actual
end
def test_merge_no_conflicts_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = {"default_env" => { "pool" => "5" } }
actual = klass.new(config).resolve
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost",
"pool" => "5"
}
}
assert_equal expected, actual
end
def test_merge_conflicts_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = {"default_env" => { "adapter" => "NOT-POSTGRES", "database" => "NOT-FOO", "pool" => "5" } }
actual = klass.new(config).resolve
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost",
"pool" => "5"
}
}
assert_equal expected, actual
end
end
class ConnectionHandlerTest < ActiveRecord::TestCase
def setup
@klass = Class.new(Base) { def self.name; 'klass'; end }
View
@@ -0,0 +1,192 @@
require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class MergeAndResolveDefaultUrlConfigTest < ActiveRecord::TestCase
def setup
@previous_database_url = ENV.delete("DATABASE_URL")
end
teardown do
ENV["DATABASE_URL"] = @previous_database_url
end
def resolve_config(config)
ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve
end
def resolve_spec(spec, config)
ConnectionSpecification::Resolver.new(resolve_config(config)).resolve(spec)
end
def test_resolver_with_database_uri_and_current_env_symbol_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = resolve_spec(:default_env, config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_resolver_with_database_uri_and_and_current_env_string_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = assert_deprecated { resolve_spec("default_env", config) }
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_resolver_with_database_uri_and_known_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "production" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
actual = resolve_spec(:production, config)
expected = { "adapter"=>"not_postgres", "database"=>"not_foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_resolver_with_database_uri_and_unknown_symbol_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
assert_raises AdapterNotSpecified do
resolve_spec(:production, config)
end
end
def test_resolver_with_database_uri_and_unknown_string_key
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_production" => { "adapter" => "not_postgres", "database" => "not_foo" } }
assert_deprecated do
assert_raises AdapterNotSpecified do
resolve_spec("production", config)
end
end
end
def test_resolver_with_database_uri_and_supplied_url
ENV['DATABASE_URL'] = "not-postgres://not-localhost/not_foo"
config = { "production" => { "adapter" => "also_not_postgres", "database" => "also_not_foo" } }
actual = resolve_spec("postgres://localhost/foo", config)
expected = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_jdbc_url
config = { "production" => { "url" => "jdbc:postgres://localhost/foo" } }
actual = resolve_config(config)
assert_equal config, actual
end
def test_environment_does_not_exist_in_config_url_does_exist
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = { "not_default_env" => { "adapter" => "not_postgres", "database" => "not_foo" } }
actual = resolve_config(config)
expect_prod = { "adapter"=>"postgresql", "database"=>"foo", "host"=>"localhost" }
assert_equal expect_prod, actual["default_env"]
end
def test_url_with_hyphenated_scheme
ENV['DATABASE_URL'] = "ibm-db://localhost/foo"
config = { "default_env" => { "adapter" => "not_postgres", "database" => "not_foo", "host" => "localhost" } }
actual = resolve_spec(:default_env, config)
expected = { "adapter"=>"ibm_db", "database"=>"foo", "host"=>"localhost" }
assert_equal expected, actual
end
def test_string_connection
config = { "default_env" => "postgres://localhost/foo" }
actual = resolve_config(config)
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
}
}
assert_equal expected, actual
end
def test_url_sub_key
config = { "default_env" => { "url" => "postgres://localhost/foo" } }
actual = resolve_config(config)
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
}
}
assert_equal expected, actual
end
def test_hash
config = { "production" => { "adapter" => "postgres", "database" => "foo" } }
actual = resolve_config(config)
assert_equal config, actual
end
def test_blank
config = {}
actual = resolve_config(config)
assert_equal config, actual
end
def test_blank_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = {}
actual = resolve_config(config)
expected = { "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost" }
assert_equal expected, actual["default_env"]
assert_equal nil, actual["production"]
assert_equal nil, actual["development"]
assert_equal nil, actual["test"]
assert_equal nil, actual[:production]
assert_equal nil, actual[:development]
assert_equal nil, actual[:test]
end
def test_url_sub_key_with_database_url
ENV['DATABASE_URL'] = "NOT-POSTGRES://localhost/NOT_FOO"
config = { "default_env" => { "url" => "postgres://localhost/foo" } }
actual = resolve_config(config)
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost"
}
}
assert_equal expected, actual
end
def test_merge_no_conflicts_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = {"default_env" => { "pool" => "5" } }
actual = resolve_config(config)
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost",
"pool" => "5"
}
}
assert_equal expected, actual
end
def test_merge_conflicts_with_database_url
ENV['DATABASE_URL'] = "postgres://localhost/foo"
config = {"default_env" => { "adapter" => "NOT-POSTGRES", "database" => "NOT-FOO", "pool" => "5" } }
actual = resolve_config(config)
expected = { "default_env" =>
{ "adapter" => "postgresql",
"database" => "foo",
"host" => "localhost",
"pool" => "5"
}
}
assert_equal expected, actual
end
end
end
end
View
@@ -92,7 +92,7 @@ def test_finds_migrations_in_numbered_directory
def test_relative_migrations
list = Dir.chdir(MIGRATIONS_ROOT) do
ActiveRecord::Migrator.migrations("valid/")
ActiveRecord::Migrator.migrations("valid")
end
migration_proxy = list.find { |item|
View
@@ -24,13 +24,18 @@ def relation
@relation ||= Relation.new FakeKlass.new('posts'), Post.arel_table
end
(Relation::MULTI_VALUE_METHODS - [:references, :extending, :order, :unscope]).each do |method|
(Relation::MULTI_VALUE_METHODS - [:references, :extending, :order, :unscope, :select]).each do |method|
test "##{method}!" do
assert relation.public_send("#{method}!", :foo).equal?(relation)
assert_equal [:foo], relation.public_send("#{method}_values")
end
end
test "#_select!" do
assert relation.public_send("_select!", :foo).equal?(relation)
assert_equal [:foo], relation.public_send("select_values")
end
test '#order!' do
assert relation.order!('name ASC').equal?(relation)
assert_equal ['name ASC'], relation.order_values
View
@@ -112,7 +112,7 @@ def test_touching_many_attributes_updates_them
previous_starting = task.starting
previous_ending = task.ending
task.touch(:starting, :ending)
assert_not_equal previous_starting, task.starting
assert_not_equal previous_ending, task.ending
assert_in_delta Time.now, task.starting, 1
@@ -170,6 +170,25 @@ def test_no_touching_threadsafe
assert !@developer.no_touching?
end
def test_no_touching_with_callbacks
klass = Class.new(ActiveRecord::Base) do
self.table_name = "developers"
attr_accessor :after_touch_called
after_touch do |user|
user.after_touch_called = true
end
end
developer = klass.first
klass.no_touching do
developer.touch
assert_not developer.after_touch_called
end
end
def test_saving_a_record_with_a_belongs_to_that_specifies_touching_the_parent_should_update_the_parent_updated_at
pet = Pet.first
owner = pet.owner
View
@@ -1,44 +1,14 @@
# encoding: utf-8
require "cases/helper"
require 'models/topic'
require 'models/reply'
require 'models/owner'
require 'models/pet'
require 'models/man'
require 'models/interest'
class AssociationValidationTest < ActiveRecord::TestCase
fixtures :topics, :owners
fixtures :topics
repair_validations(Topic, Reply)
def test_validates_size_of_association
repair_validations Owner do
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
o = Owner.new('name' => 'nopets')
assert !o.save
assert o.errors[:pets].any?
o.pets.build('name' => 'apet')
assert o.valid?
end
end
def test_validates_size_of_association_using_within
repair_validations Owner do
assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 }
o = Owner.new('name' => 'nopets')
assert !o.save
assert o.errors[:pets].any?
o.pets.build('name' => 'apet')
assert o.valid?
2.times { o.pets.build('name' => 'apet') }
assert !o.save
assert o.errors[:pets].any?
end
end
def test_validates_associated_many
Topic.validates_associated(:replies)
Reply.validates_presence_of(:content)
@@ -94,17 +64,6 @@ def test_validates_associated_missing
assert r.valid?
end
def test_validates_size_of_association_utf8
repair_validations Owner do
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
o = Owner.new('name' => 'あいうえおかきくけこ')
assert !o.save
assert o.errors[:pets].any?
o.pets.build('name' => 'あいうえおかきくけこ')
assert o.valid?
end
end
def test_validates_presence_of_belongs_to_association__parent_is_new_record
repair_validations(Interest) do
# Note that Interest and Man have the :inverse_of option set
View
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
require "cases/helper"
require 'models/owner'
require 'models/pet'
class LengthValidationTest < ActiveRecord::TestCase
fixtures :owners
repair_validations(Owner)
def test_validates_size_of_association
repair_validations Owner do
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
o = Owner.new('name' => 'nopets')
assert !o.save
assert o.errors[:pets].any?
o.pets.build('name' => 'apet')
assert o.valid?
end
end
def test_validates_size_of_association_using_within
repair_validations Owner do
assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 }
o = Owner.new('name' => 'nopets')
assert !o.save
assert o.errors[:pets].any?
o.pets.build('name' => 'apet')
assert o.valid?
2.times { o.pets.build('name' => 'apet') }
assert !o.save
assert o.errors[:pets].any?
end
end
def test_validates_size_of_association_utf8
repair_validations Owner do
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
o = Owner.new('name' => 'あいうえおかきくけこ')
assert !o.save
assert o.errors[:pets].any?
o.pets.build('name' => 'あいうえおかきくけこ')
assert o.valid?
end
end
end
View
@@ -147,6 +147,10 @@ def add_joins_and_select
has_many :lazy_readers
has_many :lazy_readers_skimmers_or_not, -> { where(skimmer: [ true, false ]) }, :class_name => 'LazyReader'
has_many :lazy_people, :through => :lazy_readers, :source => :person
has_many :lazy_readers_unscope_skimmers, -> { skimmers_or_not }, :class_name => 'LazyReader'
has_many :lazy_people_unscope_skimmers, :through => :lazy_readers_unscope_skimmers, :source => :person
def self.top(limit)
ranked_by_comments.limit_by(limit)
end
View
@@ -16,6 +16,8 @@ class LazyReader < ActiveRecord::Base
self.table_name = "readers"
default_scope -> { where(skimmer: true) }
scope :skimmers_or_not, -> { unscope(:where => :skimmer) }
belongs_to :post
belongs_to :person
end
View
@@ -31,7 +31,7 @@ class String
def pluralize(count = nil, locale = :en)
locale = count if count.is_a?(Symbol)
if count == 1
self
self.dup
else
ActiveSupport::Inflector.pluralize(self, locale)
end
View
@@ -155,7 +155,7 @@ def tableize(class_name)
#
# Singular names are not handled correctly:
#
# 'business'.classify # => "Busines"
# 'calculus'.classify # => "Calculu"
def classify(table_name)
# strip out any leading schema name
camelize(singularize(table_name.to_s.sub(/.*\./, '')))
@@ -244,8 +244,8 @@ def constantize(camel_cased_word)
next candidate if constant.const_defined?(name, false)
next candidate unless Object.const_defined?(name)
# Go down the ancestors to check it it's owned
# directly before we reach Object or the end of ancestors.
# Go down the ancestors to check if it is owned directly. The check
# stops when we reach Object or the end of ancestors tree.
constant = constant.ancestors.inject do |const, ancestor|
break const if ancestor == Object
break ancestor if ancestor.const_defined?(name, false)
View
@@ -58,6 +58,11 @@ def test_pluralize
assert_equal("blargles", "blargle".pluralize(2))
end
test 'pluralize with count = 1 still returns new string' do
name = "Kuldeep"
assert_not_same name.pluralize(1), name
end
def test_singularize
SingularToPlural.each do |singular, plural|
assert_equal(singular, plural.singularize)
View
@@ -24,9 +24,9 @@ NOTE: Bugs in the most recent released version of Ruby on Rails are likely to ge
### Creating a Bug Report
If you've found a problem in Ruby on Rails which is not a security risk, do a search in GitHub under [Issues](https://github.com/rails/rails/issues) in case it was already reported. If you find no issue addressing it you can [add a new one](https://github.com/rails/rails/issues/new). (See the next section for reporting security issues.)
If you've found a problem in Ruby on Rails which is not a security risk, do a search in GitHub under [Issues](https://github.com/rails/rails/issues) in case it has already been reported. If you do not find any issue addressing it you may proceed to [open a new one](https://github.com/rails/rails/issues/new). (See the next section for reporting security issues.)
At the minimum, your issue report needs a title and descriptive text. But that's only a minimum. You should include as much relevant information as possible. You need at least to post the code sample that has the issue. Even better is to include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix.
Your issue report should contain a title and a clear description of the issue at the bare minimum. You should include as much relevant information as possible and should at least post a code sample that demonstrates the issue. It would be even better if you could include a unit test that shows how the expected behavior is not occurring. Your goal should be to make it easy for yourself - and others - to replicate the bug and figure out a fix.
Then, don't get your hopes up! Unless you have a "Code Red, Mission Critical, the World is Coming to an End" kind of bug, you're creating this issue report in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the issue report will automatically see any activity or that others will jump to fix it. Creating an issue like this is mostly to help yourself start on the path of fixing the problem and for others to confirm it with an "I'm having this problem too" comment.
@@ -298,7 +298,7 @@ The CHANGELOG is an important part of every release. It keeps the list of change
You should add an entry to the CHANGELOG of the framework that you modified if you're adding or removing a feature, committing a bug fix or adding deprecation notices. Refactorings and documentation changes generally should not go to the CHANGELOG.
A CHANGELOG entry should summarize what was changed and should end with author's name and it should go on top of a CHANGELOG. You can use multiple lines if you need more space and you can attach code examples indented with 4 spaces. If a change is related to a specific issue, you should attach issue's number. Here is an example CHANGELOG entry:
A CHANGELOG entry should summarize what was changed and should end with author's name and it should go on top of a CHANGELOG. You can use multiple lines if you need more space and you can attach code examples indented with 4 spaces. If a change is related to a specific issue, you should attach the issue's number. Here is an example CHANGELOG entry:
```
* Summary of a change that briefly describes what was changed. You can use multiple
@@ -475,11 +475,11 @@ the same way that you appreciate feedback on your patches.
### Iterate as Necessary
It's entirely possible that the feedback you get will suggest changes. Don't get discouraged: the whole point of contributing to an active open source project is to tap into community knowledge. If people are encouraging you to tweak your code, then it's worth making the tweaks and resubmitting. If the feedback is that your code doesn't belong in the core, you might still think about releasing it as a gem.
It's entirely possible that the feedback you get will suggest changes. Don't get discouraged: the whole point of contributing to an active open source project is to tap into the knowledge of the community. If people are encouraging you to tweak your code, then it's worth making the tweaks and resubmitting. If the feedback is that your code doesn't belong in the core, you might still think about releasing it as a gem.
#### Squashing commits
One of the things that we may ask you to do is "squash your commits," which
One of the things that we may ask you to do is to "squash your commits", which
will combine all of your commits into a single commit. We prefer pull requests
that are a single commit. This makes it easier to backport changes to stable
branches, squashing makes it easier to revert bad commits, and the git history
View
@@ -1839,7 +1839,7 @@ database and send us back to the show action for the article.
### Deleting Associated Objects
If you delete an article then its associated comments will also need to be
If you delete an article, its associated comments will also need to be
deleted. Otherwise they would simply occupy space in the database. Rails allows
you to use the `dependent` option of an association to achieve this. Modify the
Article model, `app/models/article.rb`, as follows:
@@ -1857,21 +1857,21 @@ Security
### Basic Authentication
If you were to publish your blog online, anybody would be able to add, edit and
If you were to publish your blog online, anyone would be able to add, edit and
delete articles or delete comments.
Rails provides a very simple HTTP authentication system that will work nicely in
this situation.
In the `ArticlesController` we need to have a way to block access to the various
actions if the person is not authenticated, here we can use the Rails
`http_basic_authenticate_with` method, allowing access to the requested
In the `ArticlesController` we need to have a way to block access to the
various actions if the person is not authenticated. Here we can use the Rails
`http_basic_authenticate_with` method, which allows access to the requested
action if that method allows it.
To use the authentication system, we specify it at the top of our
`ArticlesController`, in this case, we want the user to be authenticated on
every action, except for `index` and `show`, so we write that in
`app/controllers/articles_controller.rb`:
`ArticlesController` in `app/controllers/articles_controller.rb`. In our case,
we want the user to be authenticated on every action except `index` and `show`,
so we write that:
```ruby
class ArticlesController < ApplicationController
View
@@ -450,7 +450,7 @@ class ::PostsController < ActionController::Base; end
test "asset urls should be protocol-relative if no request is in scope" do
app_file "app/assets/images/rails.png", "notreallyapng"
app_file "app/assets/javascripts/image_loader.js.erb", "var src='<%= image_path('rails.png') %>';"
add_to_config "config.assets.precompile = %w{image_loader.js}"
add_to_config "config.assets.precompile = %w{rails.png image_loader.js}"
add_to_config "config.asset_host = 'example.com'"
precompile!
@@ -462,7 +462,7 @@ class ::PostsController < ActionController::Base; end
app_file "app/assets/images/rails.png", "notreallyapng"
app_file "app/assets/javascripts/app.js.erb", "var src='<%= image_path('rails.png') %>';"
add_to_config "config.assets.precompile = %w{app.js}"
add_to_config "config.assets.precompile = %w{rails.png app.js}"
precompile!
assert_match "src='/sub/uri/assets/rails.png'", File.read(Dir["#{app_path}/public/assets/app-*.js"].first)