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]
t
.
references
:pasteable
,
polymorphic:
true
,
index:
{
name:
'acts_as_pasting_pasteable'
}
t
.
references
:pasted
,
polymorphic:
true
,
index:
{
name:
'acts_as_pasting_pasted'
}
t
.
string
:type
,
index:
true
t
.
string
:pasting_type
t
.
timestamps
end
...
...
lib/acts_as_pasting/pasted.rb
View file @
896f6f72
module
ActsAsPasting
module
Pasted
module
Pasted
extend
ActiveSupport
::
Concern
# 带 prefix 的 pasted_with,独立于不带 prefix 的之外
included
do
has_many
:pastings
,
as: :pasted
,
class_name:
'ActsAsPasting::Pasting'
has_many
:pastings
,
as: :pasted
# ary => [[klass, id], [klass, id]]
# ary => [obj, obj]
scope
:pasted_with_any
,
->
(
ary
)
{
scope
:pasted_with_any
,
->
(
ary
,
prefix:
''
)
{
ary
=
parsed_condition_ary
(
ary
)
ary
.
map
{
|
klass
,
id
|
joins
(
:pastings
).
where
(
'acts_as_pasting_pastings.pasteable_type = ? AND acts_as_pasting_pastings.pasteable_id = ?'
,
klass
.
constantize
.
base_class
.
name
,
id
)
}.
reduce
(
:or
)
&
.
distinct
||
self
.
none
ids
=
ary
.
map
do
|
klass
,
id
|
joins
(
:pastings
).
where
(
pastings:
{
pasteable_type:
klass
.
constantize
.
base_class
.
name
,
pasteable_id:
id
,
type:
prefix
}).
pluck
(
:id
)
end
.
reduce
(
:|
)
where
(
id:
ids
)
}
scope
:pasted_with_all
,
->
(
ary
)
{
scope
:pasted_with_all
,
->
(
ary
,
prefix:
''
)
{
ary
=
parsed_condition_ary
(
ary
)
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
(
:&
)
where
(
id:
ids
)
}
after_create
:save_paste_list
# 不包含 带 prefix 的 pasted_with
def
paste_list
pastings
.
reload
.
map
(
&
:pasteable
)
pastings
.
where
(
type:
''
).
reload
.
map
(
&
:pasteable
).
uniq
end
def
paste_list_for
klass_name
klass_name
.
constantize
.
where
(
id:
pastings
.
where
(
pasteable_type:
klass_name
.
constantize
.
base_class
.
name
).
pluck
(
:pasteable_id
)
)
end
#
def paste_list_for klass_name
#
klass_name.constantize.where(
#
id: pastings.where(pasteable_type: klass_name.constantize.base_class.name).pluck(:pasteable_id)
#
)
#
end
def
paste_list_names
paste_list
.
map
(
&
:name
)
end
def
paste_list_add
obj
pastings
.
create!
(
pasted:
self
,
pasteable:
obj
)
pastings
.
where
(
type:
''
)
.
create!
(
pasted:
self
,
pasteable:
obj
)
end
def
paste_list_remove
obj
pastings
.
where
(
pasted:
self
,
pasteable:
obj
).
destroy_all
pastings
.
where
(
type:
''
)
.
where
(
pasted:
self
,
pasteable:
obj
).
destroy_all
end
# ary => [[klass, id], [klass, id]]
# ary => [obj, obj]
# 不包含 带 prefix 的 pasted_with
def
paste_list
=
ary
ary
=
self
.
class
.
parsed_condition_ary
(
ary
)
exist_ary
=
pastings
.
where
(
pasted:
self
).
pluck
(
:pasteable_type
,
:pasteable_id
)
...
...
@@ -59,12 +64,14 @@ module ActsAsPasting
else
self
.
class
.
transaction
do
remove_ary
.
each
{
|
klass
,
id
|
pastings
.
where
(
type:
''
,
pasted:
self
,
pasteable_type:
klass
,
pasteable_id:
id
).
destroy_all
}
add_ary
.
each
{
|
klass
,
id
|
pastings
.
create!
(
type:
''
,
pasted:
self
,
pasteable_type:
klass
,
pasteable_id:
id
...
...
@@ -74,16 +81,16 @@ module ActsAsPasting
end
end
def
method_missing
name
,
*
arg
,
&
block
klass_downcase
=
/^paste_(.+)_list$/
.
match
(
name
)
&
.
[
](
1
)
#
def method_missing name, *arg, &block
#
klass_downcase = /^paste_(.+)_list$/.match(name)&.[](1)
if
klass_downcase
downcase_all_combination
(
klass_downcase
).
each
do
|
str
|
return
paste_list_for
(
str
)
if
correct_class_name?
(
str
)
end
end
super
(
name
,
*
arg
,
&
block
)
end
#
if klass_downcase
#
downcase_all_combination(klass_downcase).each do |str|
#
return paste_list_for(str) if correct_class_name?(str)
#
end
#
end
#
super(name, *arg, &block)
#
end
private
...
...
@@ -115,15 +122,20 @@ module ActsAsPasting
end
module
ClassMethods
def
pasted_with
*
klasses
def
pasted_with
*
klasses
,
prefix:
nil
klasses
.
each
do
|
klass
|
downcase
=
klass
.
name
.
underscore
.
gsub
(
'/'
,
'_'
)
downcase
=
"
#{
prefix
}#{
downcase
}
"
if
prefix
type_value
=
prefix
?
prefix
:
nil
base_class_name
=
klass
.
base_class
.
name
class_eval
<<-
RUBY
,
__FILE__
,
__LINE__
+
1
after_create :save_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
def paste_
#{
downcase
}
_ids= ids
...
...
@@ -138,18 +150,22 @@ module ActsAsPasting
if new_record?
@paste_
#{
downcase
}
_list = ary
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
remove_ary = exist_ary - ary
self.class.transaction do
remove_ary.each { |klass, id| pastings.where(
type: "
#{
type_value
}
",
pasted: self,
pasteable_type: klass,
pasteable_id: id
).destroy_all
}
add_ary.each { |klass, id| pastings.create!(
type: "
#{
type_value
}
",
pasted: self,
pasteable_type: klass,
pasteable_id: id
...
...
@@ -171,11 +187,13 @@ module ActsAsPasting
end
def
parsed_condition_ary
ary
ary
=
ary
.
compact
return
[]
unless
ary
&&
ary
.
first
case
ary
.
first
when
ActiveRecord
::
Base
ary
.
map
{
|
obj
|
[
obj
.
class
.
base_class
.
name
,
obj
.
id
]
}
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
ary
.
map
{
|
a
|
[
a
.
first
.
constantize
.
base_class
.
name
,
a
.
last
]
}
end
...
...
@@ -192,5 +210,4 @@ module ActsAsPasting
has_many
associations
,
through: :pastings
,
source: :pasted
,
**
options
end
end
end
end
lib/acts_as_pasting/pasting.rb
View file @
896f6f72
...
...
@@ -20,6 +20,8 @@
#
module
ActsAsPasting
class
Pasting
<
ApplicationRecord
self
.
inheritance_column
=
:_type_disabled
belongs_to
:pasteable
,
polymorphic:
true
belongs_to
:pasted
,
polymorphic:
true
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