Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
acts_as_pasting
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
acts_as_pasting
Commits
896f6f72
Commit
896f6f72
authored
May 10, 2020
by
Ivan Lan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add pasting type logic
parent
6402d2ab
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
52 additions
and
34 deletions
+52
-34
1_create_acts_as_pasting_pastings.rb
db/migrate/1_create_acts_as_pasting_pastings.rb
+0
-1
pasted.rb
lib/acts_as_pasting/pasted.rb
+50
-33
pasting.rb
lib/acts_as_pasting/pasting.rb
+2
-0
No files found.
db/migrate/1_create_acts_as_pasting_pastings.rb
View file @
896f6f72
...
@@ -4,7 +4,6 @@ class CreateActsAsPastingPastings < ActiveRecord::Migration[5.2]
...
@@ -4,7 +4,6 @@ class CreateActsAsPastingPastings < ActiveRecord::Migration[5.2]
t
.
references
:pasteable
,
polymorphic:
true
,
index:
{
name:
'acts_as_pasting_pasteable'
}
t
.
references
:pasteable
,
polymorphic:
true
,
index:
{
name:
'acts_as_pasting_pasteable'
}
t
.
references
:pasted
,
polymorphic:
true
,
index:
{
name:
'acts_as_pasting_pasted'
}
t
.
references
:pasted
,
polymorphic:
true
,
index:
{
name:
'acts_as_pasting_pasted'
}
t
.
string
:type
,
index:
true
t
.
string
:type
,
index:
true
t
.
string
:pasting_type
t
.
timestamps
t
.
timestamps
end
end
...
...
lib/acts_as_pasting/pasted.rb
View file @
896f6f72
module
ActsAsPasting
module
Pasted
module
Pasted
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
# 带 prefix 的 pasted_with,独立于不带 prefix 的之外
included
do
included
do
has_many
:pastings
,
as: :pasted
,
class_name:
'ActsAsPasting::Pasting'
has_many
:pastings
,
as: :pasted
# ary => [[klass, id], [klass, id]]
# ary => [[klass, id], [klass, id]]
# ary => [obj, obj]
# ary => [obj, obj]
scope
:pasted_with_any
,
->
(
ary
)
{
scope
:pasted_with_any
,
->
(
ary
,
prefix:
''
)
{
ary
=
parsed_condition_ary
(
ary
)
ary
=
parsed_condition_ary
(
ary
)
ary
.
map
{
|
klass
,
id
|
joins
(
:pastings
).
where
(
ids
=
ary
.
map
do
|
klass
,
id
|
'acts_as_pasting_pastings.pasteable_type = ? AND acts_as_pasting_pastings.pasteable_id = ?'
,
joins
(
:pastings
).
where
(
pastings:
{
klass
.
constantize
.
base_class
.
name
,
id
pasteable_type:
klass
.
constantize
.
base_class
.
name
,
pasteable_id:
id
,
type:
prefix
)
}).
pluck
(
:id
)
}.
reduce
(
:or
)
&
.
distinct
||
self
.
none
end
.
reduce
(
:|
)
where
(
id:
ids
)
}
}
scope
:pasted_with_all
,
->
(
ary
)
{
scope
:pasted_with_all
,
->
(
ary
,
prefix:
''
)
{
ary
=
parsed_condition_ary
(
ary
)
ary
=
parsed_condition_ary
(
ary
)
ids
=
ary
.
map
do
|
klass
,
id
|
ids
=
ary
.
map
do
|
klass
,
id
|
joins
(
:pastings
).
where
(
pastings:
{
pasteable_type:
klass
.
constantize
.
base_class
.
name
,
pasteable_id:
id
}).
pluck
(
:id
)
joins
(
:pastings
).
where
(
pastings:
{
pasteable_type:
klass
.
constantize
.
base_class
.
name
,
pasteable_id:
id
,
type:
prefix
}).
pluck
(
:id
)
end
.
reduce
(
:&
)
end
.
reduce
(
:&
)
where
(
id:
ids
)
where
(
id:
ids
)
}
}
after_create
:save_paste_list
after_create
:save_paste_list
# 不包含 带 prefix 的 pasted_with
def
paste_list
def
paste_list
pastings
.
reload
.
map
(
&
:pasteable
)
pastings
.
where
(
type:
''
).
reload
.
map
(
&
:pasteable
).
uniq
end
end
def
paste_list_for
klass_name
#
def paste_list_for klass_name
klass_name
.
constantize
.
where
(
#
klass_name.constantize.where(
id:
pastings
.
where
(
pasteable_type:
klass_name
.
constantize
.
base_class
.
name
).
pluck
(
:pasteable_id
)
#
id: pastings.where(pasteable_type: klass_name.constantize.base_class.name).pluck(:pasteable_id)
)
#
)
end
#
end
def
paste_list_names
def
paste_list_names
paste_list
.
map
(
&
:name
)
paste_list
.
map
(
&
:name
)
end
end
def
paste_list_add
obj
def
paste_list_add
obj
pastings
.
create!
(
pasted:
self
,
pasteable:
obj
)
pastings
.
where
(
type:
''
)
.
create!
(
pasted:
self
,
pasteable:
obj
)
end
end
def
paste_list_remove
obj
def
paste_list_remove
obj
pastings
.
where
(
pasted:
self
,
pasteable:
obj
).
destroy_all
pastings
.
where
(
type:
''
)
.
where
(
pasted:
self
,
pasteable:
obj
).
destroy_all
end
end
# ary => [[klass, id], [klass, id]]
# ary => [[klass, id], [klass, id]]
# ary => [obj, obj]
# ary => [obj, obj]
# 不包含 带 prefix 的 pasted_with
def
paste_list
=
ary
def
paste_list
=
ary
ary
=
self
.
class
.
parsed_condition_ary
(
ary
)
ary
=
self
.
class
.
parsed_condition_ary
(
ary
)
exist_ary
=
pastings
.
where
(
pasted:
self
).
pluck
(
:pasteable_type
,
:pasteable_id
)
exist_ary
=
pastings
.
where
(
pasted:
self
).
pluck
(
:pasteable_type
,
:pasteable_id
)
...
@@ -59,12 +64,14 @@ module ActsAsPasting
...
@@ -59,12 +64,14 @@ module ActsAsPasting
else
else
self
.
class
.
transaction
do
self
.
class
.
transaction
do
remove_ary
.
each
{
|
klass
,
id
|
pastings
.
where
(
remove_ary
.
each
{
|
klass
,
id
|
pastings
.
where
(
type:
''
,
pasted:
self
,
pasted:
self
,
pasteable_type:
klass
,
pasteable_type:
klass
,
pasteable_id:
id
pasteable_id:
id
).
destroy_all
).
destroy_all
}
}
add_ary
.
each
{
|
klass
,
id
|
pastings
.
create!
(
add_ary
.
each
{
|
klass
,
id
|
pastings
.
create!
(
type:
''
,
pasted:
self
,
pasted:
self
,
pasteable_type:
klass
,
pasteable_type:
klass
,
pasteable_id:
id
pasteable_id:
id
...
@@ -74,16 +81,16 @@ module ActsAsPasting
...
@@ -74,16 +81,16 @@ module ActsAsPasting
end
end
end
end
def
method_missing
name
,
*
arg
,
&
block
#
def method_missing name, *arg, &block
klass_downcase
=
/^paste_(.+)_list$/
.
match
(
name
)
&
.
[
](
1
)
#
klass_downcase = /^paste_(.+)_list$/.match(name)&.[](1)
if
klass_downcase
#
if klass_downcase
downcase_all_combination
(
klass_downcase
).
each
do
|
str
|
#
downcase_all_combination(klass_downcase).each do |str|
return
paste_list_for
(
str
)
if
correct_class_name?
(
str
)
#
return paste_list_for(str) if correct_class_name?(str)
end
#
end
end
#
end
super
(
name
,
*
arg
,
&
block
)
#
super(name, *arg, &block)
end
#
end
private
private
...
@@ -115,15 +122,20 @@ module ActsAsPasting
...
@@ -115,15 +122,20 @@ module ActsAsPasting
end
end
module
ClassMethods
module
ClassMethods
def
pasted_with
*
klasses
def
pasted_with
*
klasses
,
prefix:
nil
klasses
.
each
do
|
klass
|
klasses
.
each
do
|
klass
|
downcase
=
klass
.
name
.
underscore
.
gsub
(
'/'
,
'_'
)
downcase
=
klass
.
name
.
underscore
.
gsub
(
'/'
,
'_'
)
downcase
=
"
#{
prefix
}#{
downcase
}
"
if
prefix
type_value
=
prefix
?
prefix
:
nil
base_class_name
=
klass
.
base_class
.
name
base_class_name
=
klass
.
base_class
.
name
class_eval
<<-
RUBY
,
__FILE__
,
__LINE__
+
1
class_eval
<<-
RUBY
,
__FILE__
,
__LINE__
+
1
after_create :save_paste_
#{
downcase
}
_list
after_create :save_paste_
#{
downcase
}
_list
def paste_
#{
downcase
}
_list
def paste_
#{
downcase
}
_list
paste_list_for("
#{
klass
}
")
#{
klass
}
.where(
id: pastings.where(type: "
#{
type_value
}
", pasteable_type:
#{
klass
}
.base_class.name).pluck(:pasteable_id)
)
end
end
def paste_
#{
downcase
}
_ids= ids
def paste_
#{
downcase
}
_ids= ids
...
@@ -138,18 +150,22 @@ module ActsAsPasting
...
@@ -138,18 +150,22 @@ module ActsAsPasting
if new_record?
if new_record?
@paste_
#{
downcase
}
_list = ary
@paste_
#{
downcase
}
_list = ary
else
else
exist_ary = pastings.where(pasted: self, pasteable_type: "
#{
base_class_name
}
").pluck(:pasteable_type, :pasteable_id)
exist_ary = pastings.where(
type: "
#{
type_value
}
", pasted: self, pasteable_type: "
#{
base_class_name
}
"
).pluck(:pasteable_type, :pasteable_id)
add_ary = ary - exist_ary
add_ary = ary - exist_ary
remove_ary = exist_ary - ary
remove_ary = exist_ary - ary
self.class.transaction do
self.class.transaction do
remove_ary.each { |klass, id| pastings.where(
remove_ary.each { |klass, id| pastings.where(
type: "
#{
type_value
}
",
pasted: self,
pasted: self,
pasteable_type: klass,
pasteable_type: klass,
pasteable_id: id
pasteable_id: id
).destroy_all
).destroy_all
}
}
add_ary.each { |klass, id| pastings.create!(
add_ary.each { |klass, id| pastings.create!(
type: "
#{
type_value
}
",
pasted: self,
pasted: self,
pasteable_type: klass,
pasteable_type: klass,
pasteable_id: id
pasteable_id: id
...
@@ -171,11 +187,13 @@ module ActsAsPasting
...
@@ -171,11 +187,13 @@ module ActsAsPasting
end
end
def
parsed_condition_ary
ary
def
parsed_condition_ary
ary
ary
=
ary
.
compact
return
[]
unless
ary
&&
ary
.
first
case
ary
.
first
case
ary
.
first
when
ActiveRecord
::
Base
when
ActiveRecord
::
Base
ary
.
map
{
|
obj
|
[
obj
.
class
.
base_class
.
name
,
obj
.
id
]
}
ary
.
map
{
|
obj
|
[
obj
.
class
.
base_class
.
name
,
obj
.
id
]
}
when
Hash
when
Hash
ary
.
map
{
|
h
|
[
h
[
:paste_type
].
constantize
.
base_class
.
name
,
h
[
:paste
_id
]]
}
ary
.
map
{
|
h
|
[
h
[
:pasted_type
].
constantize
.
base_class
.
name
,
h
[
:pasted
_id
]]
}
else
else
ary
.
map
{
|
a
|
[
a
.
first
.
constantize
.
base_class
.
name
,
a
.
last
]
}
ary
.
map
{
|
a
|
[
a
.
first
.
constantize
.
base_class
.
name
,
a
.
last
]
}
end
end
...
@@ -192,5 +210,4 @@ module ActsAsPasting
...
@@ -192,5 +210,4 @@ module ActsAsPasting
has_many
associations
,
through: :pastings
,
source: :pasted
,
**
options
has_many
associations
,
through: :pastings
,
source: :pasted
,
**
options
end
end
end
end
end
end
end
lib/acts_as_pasting/pasting.rb
View file @
896f6f72
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
#
#
module
ActsAsPasting
module
ActsAsPasting
class
Pasting
<
ApplicationRecord
class
Pasting
<
ApplicationRecord
self
.
inheritance_column
=
:_type_disabled
belongs_to
:pasteable
,
polymorphic:
true
belongs_to
:pasteable
,
polymorphic:
true
belongs_to
:pasted
,
polymorphic:
true
belongs_to
:pasted
,
polymorphic:
true
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
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 comment