Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
public
/
sequelize
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
不要怂,就是干,撸起袖子干!
Commit 72941d80
authored
Dec 19, 2013
by
Mick Hansen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tests for fetching N:M with aliases + more refactoring
1 parent
23c6c854
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
51 deletions
lib/associations/has-many-double-linked.js
lib/associations/has-many.js
package.json
test/associations/has-many.test.js
test/dao-factory.test.js
lib/associations/has-many-double-linked.js
View file @
72941d8
...
...
@@ -2,8 +2,8 @@ var Utils = require('./../utils')
,
Transaction
=
require
(
'./../transaction'
)
module
.
exports
=
(
function
()
{
var
HasManyDoubleLinked
=
function
(
defini
tion
,
instance
)
{
this
.
__factory
=
defini
tion
var
HasManyDoubleLinked
=
function
(
associa
tion
,
instance
)
{
this
.
association
=
associa
tion
this
.
instance
=
instance
// Alias the quoting methods for code brevity
...
...
@@ -17,32 +17,32 @@ module.exports = (function() {
var
customEventEmitter
=
new
Utils
.
CustomEventEmitter
(
function
()
{
var
where
=
{}
,
through
=
self
.
__factory
.
through
,
through
=
self
.
association
.
through
,
options
=
_options
||
{}
,
queryOptions
=
{}
,
association
=
self
.
__factory
.
target
.
associations
[
self
.
__factory
.
associationAccessor
]
,
targetAssociation
=
self
.
association
.
targetAssociation
//fully qualify
var
instancePrimaryKeys
=
Object
.
keys
(
self
.
instance
.
daoFactory
.
primaryKeys
)
,
instancePrimaryKey
=
instancePrimaryKeys
.
length
>
0
?
instancePrimaryKeys
[
0
]
:
'id'
where
[
through
.
tableName
+
"."
+
self
.
__factory
.
identifier
]
=
self
.
instance
[
instancePrimaryKey
]
where
[
through
.
tableName
+
"."
+
self
.
association
.
identifier
]
=
self
.
instance
[
instancePrimaryKey
]
var
primaryKeys
=
Object
.
keys
(
through
.
primaryKeys
)
,
foreignKey
=
primaryKeys
.
filter
(
function
(
pk
)
{
return
pk
!=
self
.
__factory
.
identifier
})[
0
]
,
foreignPrimary
=
Object
.
keys
(
self
.
__factory
.
target
.
primaryKeys
)
,
foreignKey
=
primaryKeys
.
filter
(
function
(
pk
)
{
return
pk
!=
self
.
association
.
identifier
})[
0
]
,
foreignPrimary
=
Object
.
keys
(
self
.
association
.
target
.
primaryKeys
)
foreignPrimary
=
foreignPrimary
.
length
===
1
?
foreignPrimary
[
0
]
:
'id'
where
[
through
.
tableName
+
"."
+
foreignKey
]
=
{
join
:
self
.
__factory
.
target
.
tableName
+
"."
+
foreignPrimary
}
where
[
through
.
tableName
+
"."
+
foreignKey
]
=
{
join
:
self
.
association
.
target
.
tableName
+
"."
+
foreignPrimary
}
if
(
Object
(
association
.
through
)
===
a
ssociation
.
through
)
{
if
(
Object
(
targetAssociation
.
through
)
===
targetA
ssociation
.
through
)
{
queryOptions
.
hasJoinTableModel
=
true
queryOptions
.
joinTableModel
=
through
if
(
!
options
.
attributes
)
{
options
.
attributes
=
[
self
.
QueryInterface
.
quoteIdentifier
(
self
.
__factory
.
target
.
tableName
)
+
".*"
self
.
QueryInterface
.
quoteIdentifier
(
self
.
association
.
target
.
tableName
)
+
".*"
]
}
...
...
@@ -65,14 +65,14 @@ module.exports = (function() {
if
(
options
.
where
)
{
if
(
Array
.
isArray
(
options
.
where
))
{
smart
=
Utils
.
smartWhere
([
where
,
options
.
where
],
self
.
__factory
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
smart
=
Utils
.
compileSmartWhere
.
call
(
self
.
__factory
.
target
,
smart
,
self
.
__factory
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
smart
=
Utils
.
smartWhere
([
where
,
options
.
where
],
self
.
association
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
smart
=
Utils
.
compileSmartWhere
.
call
(
self
.
association
.
target
,
smart
,
self
.
association
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
if
(
smart
.
length
>
0
)
{
options
.
where
=
smart
}
}
else
{
smart
=
Utils
.
smartWhere
([
where
,
options
.
where
],
self
.
__factory
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
smart
=
Utils
.
compileSmartWhere
.
call
(
self
.
__factory
.
target
,
smart
,
self
.
__factory
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
smart
=
Utils
.
smartWhere
([
where
,
options
.
where
],
self
.
association
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
smart
=
Utils
.
compileSmartWhere
.
call
(
self
.
association
.
target
,
smart
,
self
.
association
.
target
.
daoFactoryManager
.
sequelize
.
options
.
dialect
)
if
(
smart
.
length
>
0
)
{
options
.
where
=
smart
}
...
...
@@ -81,7 +81,7 @@ module.exports = (function() {
options
.
where
=
where
;
}
self
.
__factory
.
target
.
findAllJoin
(
through
.
tableName
,
options
,
queryOptions
)
self
.
association
.
target
.
findAllJoin
(
through
.
tableName
,
options
,
queryOptions
)
.
on
(
'success'
,
function
(
objects
)
{
customEventEmitter
.
emit
(
'success'
,
objects
)
})
.
on
(
'error'
,
function
(
err
){
customEventEmitter
.
emit
(
'error'
,
err
)
})
.
on
(
'sql'
,
function
(
sql
)
{
customEventEmitter
.
emit
(
'sql'
,
sql
)})
...
...
@@ -93,10 +93,10 @@ module.exports = (function() {
HasManyDoubleLinked
.
prototype
.
injectSetter
=
function
(
emitterProxy
,
oldAssociations
,
newAssociations
,
defaultAttributes
)
{
var
self
=
this
,
chainer
=
new
Utils
.
QueryChainer
()
,
association
=
self
.
__factory
.
target
.
associations
[
self
.
__factory
.
associationAccessor
]
,
foreignIdentifier
=
association
.
isSelfAssociation
?
association
.
foreignIdentifier
:
a
ssociation
.
identifier
,
sourceKeys
=
Object
.
keys
(
self
.
__factory
.
source
.
primaryKeys
)
,
targetKeys
=
Object
.
keys
(
self
.
__factory
.
target
.
primaryKeys
)
,
targetAssociation
=
self
.
association
.
targetAssociation
,
foreignIdentifier
=
targetAssociation
.
isSelfAssociation
?
targetAssociation
.
foreignIdentifier
:
targetA
ssociation
.
identifier
,
sourceKeys
=
Object
.
keys
(
self
.
association
.
source
.
primaryKeys
)
,
targetKeys
=
Object
.
keys
(
self
.
association
.
target
.
primaryKeys
)
,
obsoleteAssociations
=
[]
,
changedAssociations
=
[]
,
options
=
{}
...
...
@@ -120,13 +120,13 @@ module.exports = (function() {
if
(
!
newObj
)
{
obsoleteAssociations
.
push
(
old
)
}
else
if
(
Object
(
association
.
through
)
===
a
ssociation
.
through
)
{
}
else
if
(
Object
(
targetAssociation
.
through
)
===
targetA
ssociation
.
through
)
{
var
changedAssociation
=
{
where
:
{},
attributes
:
Utils
.
_
.
defaults
({},
newObj
[
self
.
__factory
.
through
.
name
],
defaultAttributes
)
attributes
:
Utils
.
_
.
defaults
({},
newObj
[
self
.
association
.
through
.
name
],
defaultAttributes
)
}
changedAssociation
.
where
[
self
.
__factory
.
identifier
]
=
self
.
instance
[
self
.
__factory
.
identifier
]
||
self
.
instance
.
id
changedAssociation
.
where
[
self
.
association
.
identifier
]
=
self
.
instance
[
self
.
association
.
identifier
]
||
self
.
instance
.
id
changedAssociation
.
where
[
foreignIdentifier
]
=
newObj
[
foreignIdentifier
]
||
newObj
.
id
changedAssociations
.
push
(
changedAssociation
)
...
...
@@ -140,32 +140,32 @@ module.exports = (function() {
var
where
=
{}
where
[
self
.
__factory
.
identifier
]
=
((
sourceKeys
.
length
===
1
)
?
self
.
instance
[
sourceKeys
[
0
]]
:
self
.
instance
.
id
)
where
[
self
.
association
.
identifier
]
=
((
sourceKeys
.
length
===
1
)
?
self
.
instance
[
sourceKeys
[
0
]]
:
self
.
instance
.
id
)
where
[
foreignIdentifier
]
=
foreignIds
chainer
.
add
(
self
.
__factory
.
through
.
destroy
(
where
,
options
))
chainer
.
add
(
self
.
association
.
through
.
destroy
(
where
,
options
))
}
if
(
unassociatedObjects
.
length
>
0
)
{
var
bulk
=
unassociatedObjects
.
map
(
function
(
unassociatedObject
)
{
var
attributes
=
{}
attributes
[
self
.
__factory
.
identifier
]
=
((
sourceKeys
.
length
===
1
)
?
self
.
instance
[
sourceKeys
[
0
]]
:
self
.
instance
.
id
)
attributes
[
self
.
association
.
identifier
]
=
((
sourceKeys
.
length
===
1
)
?
self
.
instance
[
sourceKeys
[
0
]]
:
self
.
instance
.
id
)
attributes
[
foreignIdentifier
]
=
((
targetKeys
.
length
===
1
)
?
unassociatedObject
[
targetKeys
[
0
]]
:
unassociatedObject
.
id
)
if
(
Object
(
association
.
through
)
===
a
ssociation
.
through
)
{
attributes
=
Utils
.
_
.
defaults
(
attributes
,
unassociatedObject
[
a
ssociation
.
through
.
name
],
defaultAttributes
)
if
(
Object
(
targetAssociation
.
through
)
===
targetA
ssociation
.
through
)
{
attributes
=
Utils
.
_
.
defaults
(
attributes
,
unassociatedObject
[
targetA
ssociation
.
through
.
name
],
defaultAttributes
)
}
return
attributes
})
chainer
.
add
(
self
.
__factory
.
through
.
bulkCreate
(
bulk
,
options
))
chainer
.
add
(
self
.
association
.
through
.
bulkCreate
(
bulk
,
options
))
}
if
(
changedAssociations
.
length
>
0
)
{
changedAssociations
.
forEach
(
function
(
assoc
)
{
chainer
.
add
(
self
.
__factory
.
through
.
update
(
assoc
.
attributes
,
assoc
.
where
,
options
))
chainer
.
add
(
self
.
association
.
through
.
update
(
assoc
.
attributes
,
assoc
.
where
,
options
))
})
}
...
...
@@ -177,27 +177,25 @@ module.exports = (function() {
}
HasManyDoubleLinked
.
prototype
.
injectAdder
=
function
(
emitterProxy
,
newAssociation
,
additionalAttributes
,
exists
)
{
var
attributes
=
{}
,
association
=
this
.
__factory
.
target
.
associations
[
this
.
__factory
.
associationAccessor
]
,
foreignIdentifier
=
association
.
isSelfAssociation
?
association
.
foreignIdentifier
:
a
ssociation
.
identifier
;
var
attributes
=
{}
,
targetAssociation
=
this
.
association
.
targetAssociation
,
foreignIdentifier
=
targetAssociation
.
isSelfAssociation
?
targetAssociation
.
foreignIdentifier
:
targetA
ssociation
.
identifier
;
var
sourceKeys
=
Object
.
keys
(
this
.
__factory
.
source
.
primaryKeys
);
var
targetKeys
=
Object
.
keys
(
this
.
__factory
.
target
.
primaryKeys
);
var
sourceKeys
=
Object
.
keys
(
this
.
association
.
source
.
primaryKeys
);
var
targetKeys
=
Object
.
keys
(
this
.
association
.
target
.
primaryKeys
);
attributes
[
this
.
__factory
.
identifier
]
=
((
sourceKeys
.
length
===
1
)
?
this
.
instance
[
sourceKeys
[
0
]]
:
this
.
instance
.
id
)
attributes
[
this
.
association
.
identifier
]
=
((
sourceKeys
.
length
===
1
)
?
this
.
instance
[
sourceKeys
[
0
]]
:
this
.
instance
.
id
)
attributes
[
foreignIdentifier
]
=
((
targetKeys
.
length
===
1
)
?
newAssociation
[
targetKeys
[
0
]]
:
newAssociation
.
id
)
if
(
exists
)
{
// implies hasJoinTableModel === true
var
where
=
attributes
attributes
=
Utils
.
_
.
defaults
({},
newAssociation
[
association
.
through
.
name
],
additionalAttributes
)
a
ssociation
.
through
.
update
(
attributes
,
where
).
proxy
(
emitterProxy
)
targetA
ssociation
.
through
.
update
(
attributes
,
where
).
proxy
(
emitterProxy
)
}
else
{
if
(
Object
(
association
.
through
)
===
association
.
through
)
{
attributes
=
Utils
.
_
.
defaults
(
attributes
,
newAssociation
[
association
.
through
.
name
],
additionalAttributes
)
}
attributes
=
Utils
.
_
.
defaults
(
attributes
,
newAssociation
[
targetAssociation
.
through
.
name
],
additionalAttributes
)
this
.
__factory
.
through
.
create
(
attributes
)
this
.
association
.
through
.
create
(
attributes
)
.
success
(
function
()
{
emitterProxy
.
emit
(
'success'
,
newAssociation
)
})
.
error
(
function
(
err
)
{
emitterProxy
.
emit
(
'error'
,
err
)
})
.
on
(
'sql'
,
function
(
sql
)
{
emitterProxy
.
emit
(
'sql'
,
sql
)
})
...
...
lib/associations/has-many.js
View file @
72941d8
...
...
@@ -231,7 +231,7 @@ module.exports = (function() {
return
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
instance
[
self
.
accessors
.
get
]()
.
success
(
function
(
oldAssociatedObjects
)
{
var
Class
=
Object
(
self
.
through
)
===
self
.
through
?
HasManyMultiLinked
:
HasManySingleLinked
var
Class
=
self
.
doubleLinked
?
HasManyMultiLinked
:
HasManySingleLinked
new
Class
(
self
,
instance
).
injectSetter
(
emitter
,
oldAssociatedObjects
,
newAssociatedObjects
,
defaultAttributes
)
})
.
error
(
function
(
err
)
{
...
...
@@ -256,7 +256,7 @@ module.exports = (function() {
.
error
(
function
(
err
){
emitter
.
emit
(
'error'
,
err
)})
.
success
(
function
(
currentAssociatedObjects
)
{
if
(
currentAssociatedObjects
.
length
===
0
||
self
.
hasJoinTableModel
===
true
)
{
var
Class
=
Object
(
self
.
through
)
===
self
.
through
?
HasManyMultiLinked
:
HasManySingleLinked
var
Class
=
self
.
doubleLinked
?
HasManyMultiLinked
:
HasManySingleLinked
new
Class
(
self
,
instance
).
injectAdder
(
emitter
,
newAssociatedObject
,
additionalAttributes
,
!!
currentAssociatedObjects
.
length
)
}
else
{
emitter
.
emit
(
'success'
,
newAssociatedObject
);
...
...
package.json
View file @
72941d8
...
...
@@ -64,7 +64,8 @@
"chai-spies"
:
"~0.5.1"
,
"lcov-result-merger"
:
"0.0.2"
,
"istanbul"
:
"~0.1.45"
,
"coveralls"
:
"~2.5.0"
"coveralls"
:
"~2.5.0"
,
"async"
:
"~0.2.9"
},
"keywords"
:
[
"mysql"
,
...
...
@@ -84,4 +85,4 @@
"node"
:
">=0.6.21"
},
"license"
:
"MIT"
}
\ No newline at end of file
}
test/associations/has-many.test.js
View file @
72941d8
...
...
@@ -909,9 +909,9 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
Group
.
hasMany
(
User
,
{
as
:
'MyUsers'
,
through
:
'group_user'
})
this
.
sequelize
.
sync
({
force
:
true
}).
success
(
function
()
{
self
.
sequelize
.
query
(
"SHOW TABLES LIKE 'group_user'"
).
success
(
function
(
res
)
{
expect
(
res
).
to
.
deep
.
equal
([
'group_user'
]
)
done
()
self
.
sequelize
.
getQueryInterface
().
showAllTables
().
success
(
function
(
result
)
{
expect
(
result
.
indexOf
(
'group_user'
)).
not
.
to
.
equal
(
-
1
)
done
()
})
})
})
...
...
@@ -926,9 +926,9 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
Group
.
hasMany
(
User
,
{
as
:
'MyUsers'
,
through
:
UserGroup
})
this
.
sequelize
.
sync
({
force
:
true
}).
success
(
function
()
{
self
.
sequelize
.
query
(
"SHOW TABLES LIKE 'user_groups'"
).
success
(
function
(
res
)
{
expect
(
res
).
to
.
deep
.
equal
([
'user_groups'
]
)
done
()
self
.
sequelize
.
getQueryInterface
().
showAllTables
().
success
(
function
(
result
)
{
expect
(
result
.
indexOf
(
'user_groups'
)).
not
.
to
.
equal
(
-
1
)
done
()
})
})
})
...
...
test/dao-factory.test.js
View file @
72941d8
...
...
@@ -11,6 +11,7 @@ var chai = require('chai')
,
datetime
=
require
(
'chai-datetime'
)
,
_
=
require
(
'lodash'
)
,
moment
=
require
(
'moment'
)
,
async
=
require
(
'async'
)
chai
.
use
(
datetime
)
chai
.
Assertion
.
includeStack
=
true
...
...
@@ -2451,6 +2452,120 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
})
})
})
describe
(
'hasMany (N:M) with alias'
,
function
()
{
beforeEach
(
function
(
done
)
{
this
.
Product
=
this
.
sequelize
.
define
(
'Product'
,
{
title
:
Sequelize
.
STRING
})
this
.
Tag
=
this
.
sequelize
.
define
(
'Tag'
,
{
name
:
Sequelize
.
STRING
})
done
();
})
it
(
'returns the associated models when using through as string and alias'
,
function
(
done
)
{
var
self
=
this
this
.
Product
.
hasMany
(
this
.
Tag
,
{
as
:
'Tags'
,
through
:
'product_tag'
})
this
.
Tag
.
hasMany
(
this
.
Product
,
{
as
:
'Products'
,
through
:
'product_tag'
})
this
.
sequelize
.
sync
().
done
(
function
(
err
)
{
async
.
auto
({
createProducts
:
function
(
callback
)
{
self
.
Product
.
bulkCreate
([
{
title
:
'Chair'
},
{
title
:
'Desk'
},
{
title
:
'Handbag'
},
{
title
:
'Dress'
},
{
title
:
'Jan'
}
]).
done
(
callback
)
},
// bulkCreate doesn't include id for some reason, not going to fix tis now
products
:
[
'createProducts'
,
function
(
callback
)
{
self
.
Product
.
findAll
().
done
(
callback
)
}],
createTags
:
function
(
callback
)
{
self
.
Tag
.
bulkCreate
([
{
title
:
'Furniture'
},
{
title
:
'Clothing'
},
{
title
:
'People'
}
]).
done
(
callback
)
},
tags
:
[
'createTags'
,
function
(
callback
)
{
self
.
Tag
.
findAll
().
done
(
callback
)
}],
},
function
(
err
,
results
)
{
expect
(
err
).
not
.
to
.
exist
var
products
=
results
.
products
,
tags
=
results
.
tags
async
.
parallel
([
function
(
callback
)
{
products
[
0
].
setTags
([
tags
[
0
],
tags
[
1
]]).
done
(
callback
)
},
function
(
callback
)
{
products
[
1
].
addTag
(
tags
[
0
]).
done
(
callback
)
},
function
(
callback
)
{
products
[
2
].
addTag
(
tags
[
1
]).
done
(
callback
)
},
function
(
callback
)
{
products
[
3
].
setTags
([
tags
[
1
]]).
done
(
callback
)
},
function
(
callback
)
{
products
[
4
].
setTags
([
tags
[
2
]]).
done
(
callback
)
}
],
function
(
err
)
{
expect
(
err
).
not
.
to
.
exist
async
.
parallel
([
function
(
callback
)
{
self
.
Tag
.
find
({
where
:
{
id
:
tags
[
0
].
id
},
include
:
[
{
model
:
self
.
Product
,
as
:
'Products'
}
]
}).
done
(
function
(
err
,
tag
)
{
expect
(
tag
).
to
.
exist
expect
(
tag
.
products
.
length
).
to
.
equal
(
2
)
callback
()
})
},
function
(
callback
)
{
tags
[
1
].
getProducts
().
done
(
function
(
err
,
products
)
{
expect
(
products
.
length
).
to
.
equal
(
3
)
callback
()
})
},
function
(
callback
)
{
self
.
Product
.
find
({
where
:
{
id
:
products
[
0
].
id
},
include
:
[
{
model
:
self
.
Tag
,
as
:
'Tags'
}
]
}).
done
(
function
(
err
,
product
)
{
expect
(
product
).
to
.
exist
expect
(
product
.
tags
.
length
).
to
.
equal
(
2
)
callback
()
})
},
function
(
callback
)
{
products
[
1
].
getTags
().
done
(
function
(
err
,
tags
)
{
expect
(
tags
.
length
).
to
.
equal
(
1
)
callback
()
})
},
],
done
)
})
})
})
})
it
(
'returns the associated models when using through as model and alias'
)
})
})
describe
(
'queryOptions'
,
function
()
{
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment