mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fixed that has_and_belongs_to_many didn't respect single table inheritance types #1081 [Florian Weber]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1641 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
38e0862c81
commit
df95128e94
13 changed files with 43 additions and 8 deletions
|
@ -1,5 +1,7 @@
|
||||||
*SVN*
|
*SVN*
|
||||||
|
|
||||||
|
* Fixed that has_and_belongs_to_many didn't respect single table inheritance types #1081 [Florian Weber]
|
||||||
|
|
||||||
* Speed up ActiveRecord#method_missing for the common case (read_attribute).
|
* Speed up ActiveRecord#method_missing for the common case (read_attribute).
|
||||||
|
|
||||||
* Only notify observers on after_find and after_initialize if these methods are defined on the model. [skaes@web.de]
|
* Only notify observers on after_find and after_initialize if these methods are defined on the model. [skaes@web.de]
|
||||||
|
|
|
@ -158,6 +158,15 @@ module ActiveRecord
|
||||||
"j.#{@association_class_primary_key_name} = #{@owner.quoted_id} "
|
"j.#{@association_class_primary_key_name} = #{@owner.quoted_id} "
|
||||||
|
|
||||||
@finder_sql << " AND #{interpolate_sql(@options[:conditions])}" if @options[:conditions]
|
@finder_sql << " AND #{interpolate_sql(@options[:conditions])}" if @options[:conditions]
|
||||||
|
|
||||||
|
unless @association_class.descends_from_active_record?
|
||||||
|
type_condition = @association_class.send(:subclasses).inject("t.#{@association_class.inheritance_column} = '#{@association_class.name.demodulize}' ") do |condition, subclass|
|
||||||
|
condition << "OR t.#{@association_class.inheritance_column} = '#{subclass.name.demodulize}' "
|
||||||
|
end
|
||||||
|
|
||||||
|
@finder_sql << " AND (#{type_condition})"
|
||||||
|
end
|
||||||
|
|
||||||
@finder_sql << " ORDER BY #{@order}" if @order
|
@finder_sql << " ORDER BY #{@order}" if @order
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1105,4 +1105,18 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
||||||
new_developer.save
|
new_developer.save
|
||||||
assert_equal 2, new_developer.projects.length
|
assert_equal 2, new_developer.projects.length
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_consider_type
|
||||||
|
developer = Developer.find(:first)
|
||||||
|
special_project = SpecialProject.create("name" => "Special Project")
|
||||||
|
|
||||||
|
other_project = developer.projects.first
|
||||||
|
developer.special_projects << special_project
|
||||||
|
developer.reload
|
||||||
|
|
||||||
|
assert developer.projects.include?(special_project)
|
||||||
|
assert developer.special_projects.include?(special_project)
|
||||||
|
assert !developer.special_projects.include?(other_project)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -114,7 +114,7 @@ class BasicsTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_attributes_hash
|
def test_attributes_hash
|
||||||
assert_equal @loaded_fixtures['projects']['active_record'].to_hash, Project.find(:first).attributes
|
assert_equal @loaded_fixtures['computers']['workstation'].to_hash, Computer.find(:first).attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create
|
def test_create
|
||||||
|
|
|
@ -44,6 +44,7 @@ CREATE TABLE developers (
|
||||||
CREATE TABLE projects (
|
CREATE TABLE projects (
|
||||||
id int generated by default as identity (start with +10000),
|
id int generated by default as identity (start with +10000),
|
||||||
name varchar(100) default NULL,
|
name varchar(100) default NULL,
|
||||||
|
type varchar(255) default NULL,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ CREATE TABLE `developers` (
|
||||||
CREATE TABLE `projects` (
|
CREATE TABLE `projects` (
|
||||||
`id` int(11) NOT NULL auto_increment,
|
`id` int(11) NOT NULL auto_increment,
|
||||||
`name` varchar(100) default NULL,
|
`name` varchar(100) default NULL,
|
||||||
|
`type` VARCHAR(255) NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) TYPE=InnoDB;
|
) TYPE=InnoDB;
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ create table developers (
|
||||||
create table projects (
|
create table projects (
|
||||||
id integer not null,
|
id integer not null,
|
||||||
name varchar(100) default null,
|
name varchar(100) default null,
|
||||||
|
type varchar(255) default null,
|
||||||
primary key (id)
|
primary key (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ SELECT setval('developers_id_seq', 100);
|
||||||
CREATE TABLE projects (
|
CREATE TABLE projects (
|
||||||
id serial,
|
id serial,
|
||||||
name character varying(100),
|
name character varying(100),
|
||||||
|
type varchar(255),
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
);
|
);
|
||||||
SELECT setval('projects_id_seq', 100);
|
SELECT setval('projects_id_seq', 100);
|
||||||
|
|
|
@ -40,7 +40,8 @@ CREATE TABLE 'developers' (
|
||||||
|
|
||||||
CREATE TABLE 'projects' (
|
CREATE TABLE 'projects' (
|
||||||
'id' INTEGER PRIMARY KEY NOT NULL,
|
'id' INTEGER PRIMARY KEY NOT NULL,
|
||||||
'name' TEXT DEFAULT NULL
|
'name' TEXT DEFAULT NULL,
|
||||||
|
'type' VARCHAR(255) DEFAULT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE 'developers_projects' (
|
CREATE TABLE 'developers_projects' (
|
||||||
|
|
|
@ -39,7 +39,8 @@ CREATE TABLE developers (
|
||||||
|
|
||||||
CREATE TABLE projects (
|
CREATE TABLE projects (
|
||||||
id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
|
id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
|
||||||
name varchar(100) default NULL
|
name varchar(100) default NULL,
|
||||||
|
type varchar(255) default NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE developers_projects (
|
CREATE TABLE developers_projects (
|
||||||
|
|
3
activerecord/test/fixtures/developer.rb
vendored
3
activerecord/test/fixtures/developer.rb
vendored
|
@ -1,6 +1,7 @@
|
||||||
class Developer < ActiveRecord::Base
|
class Developer < ActiveRecord::Base
|
||||||
has_and_belongs_to_many :projects
|
has_and_belongs_to_many :projects
|
||||||
|
has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id'
|
||||||
|
|
||||||
validates_inclusion_of :salary, :in => 50000..200000
|
validates_inclusion_of :salary, :in => 50000..200000
|
||||||
validates_length_of :name, :within => 3..20
|
validates_length_of :name, :within => 3..20
|
||||||
end
|
end
|
||||||
|
|
3
activerecord/test/fixtures/subscriber.rb
vendored
3
activerecord/test/fixtures/subscriber.rb
vendored
|
@ -3,3 +3,6 @@ class Subscriber < ActiveRecord::Base
|
||||||
"nick"
|
"nick"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class SpecialSubscriber < Subscriber
|
||||||
|
end
|
|
@ -1,9 +1,10 @@
|
||||||
require 'abstract_unit'
|
require 'abstract_unit'
|
||||||
require 'fixtures/company'
|
require 'fixtures/company'
|
||||||
require 'fixtures/project'
|
require 'fixtures/project'
|
||||||
|
require 'fixtures/subscriber'
|
||||||
|
|
||||||
class InheritanceTest < Test::Unit::TestCase
|
class InheritanceTest < Test::Unit::TestCase
|
||||||
fixtures :companies, :projects
|
fixtures :companies, :projects, :subscribers
|
||||||
|
|
||||||
def test_a_bad_type_column
|
def test_a_bad_type_column
|
||||||
#SQLServer need to turn Identity Insert On before manually inserting into the Identity column
|
#SQLServer need to turn Identity Insert On before manually inserting into the Identity column
|
||||||
|
@ -125,9 +126,8 @@ class InheritanceTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_inheritance_without_mapping
|
def test_inheritance_without_mapping
|
||||||
assert_kind_of SpecialProject, SpecialProject.find(1)
|
assert_kind_of SpecialSubscriber, SpecialSubscriber.find("webster132")
|
||||||
assert_nothing_raised { SpecialProject.create("name" => "And breaaaaathe!") }
|
assert_nothing_raised { SpecialSubscriber.create("name" => "And breaaaaathe!", "id" => "smartass") }
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
Loading…
Reference in a new issue