7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
# File 'lib/imyou/models.rb', line 7
def has_imyou(name_column=nil)
class_eval do
has_many :imyou_nicknames, -> { order(id: :asc) }, class_name: 'Imyou::Nickname', as: :model, dependent: :destroy
accepts_nested_attributes_for :imyou_nicknames,
allow_destroy: true,
reject_if: ->(attributes) { attributes['name'].blank? }
scope :with_nicknames, -> { preload(:imyou_nicknames) }
scope :match_by_nickname, ->(nickname, with_name_column: true) do
if Gem::Version.new(ActiveRecord.version) >= Gem::Version.new(5)
records = self.left_outer_joins(:imyou_nicknames).where(Imyou::Nickname.arel_table[:name].eq(nickname))
unless name_column.nil? || with_name_column == false
records.or!(self.left_outer_joins(:imyou_nicknames).where(name_column => nickname))
end
else
joined_records = self.joins(<<~SQL
LEFT OUTER JOIN #{Imyou::Nickname.quoted_table_name}
ON
#{Imyou::Nickname.quoted_table_name}.#{connection.quote_column_name(:model_id)} = #{self.quoted_table_name}.#{connection.quote_column_name(:id)}
AND
#{Imyou::Nickname.quoted_table_name}.#{connection.quote_column_name(:model_type)} = #{connection.quote(self.name)}
SQL
)
arel_nickname_column = Imyou::Nickname.arel_table[:name]
records = if name_column.nil? || with_name_column == false
joined_records.where(
arel_nickname_column.eq(nickname)
)
else
arel_name_column = self.arel_table[name_column]
joined_records.where(
arel_nickname_column.eq(nickname).or(
arel_name_column.eq(nickname)
)
)
end
end
records
end
scope :partial_match_by_nickname, ->(nickname, with_name_column: true) do
if Gem::Version.new(ActiveRecord.version) >= Gem::Version.new(5)
records = self.left_outer_joins(:imyou_nicknames).where(Imyou::Nickname.arel_table[:name].matches("%#{sanitize_sql_like(nickname)}%", '\\'))
unless name_column.nil? || with_name_column == false
records.or!(self.left_outer_joins(:imyou_nicknames).where(
self.arel_table[name_column].matches("%#{sanitize_sql_like(nickname)}%", '\\'))
)
end
else
joined_records = self.joins(<<~SQL
LEFT OUTER JOIN #{Imyou::Nickname.quoted_table_name}
ON
#{Imyou::Nickname.quoted_table_name}.#{connection.quote_column_name(:model_id)} = #{self.quoted_table_name}.#{connection.quote_column_name(:id)}
AND
#{Imyou::Nickname.quoted_table_name}.#{connection.quote_column_name(:model_type)} = #{connection.quote(self.name)}
SQL
)
arel_nickname_column = Imyou::Nickname.arel_table[:name]
records = if name_column.nil? || with_name_column == false
joined_records.where(
arel_nickname_column.matches("%#{sanitize_sql_like(nickname)}%", '\\')
)
else
arel_name_column = self.arel_table[name_column]
joined_records.where(
arel_nickname_column.matches("%#{sanitize_sql_like(nickname)}%", '\\').or(
arel_name_column.matches("%#{sanitize_sql_like(nickname)}%", '\\')
)
)
end
end
records
end
alias_method :save_with_nicknames, :save
alias_method :save_with_nicknames!, :save!
def self.has_imyou?
true
end
def nicknames
if new_record?
self.imyou_nicknames.map(&:name)
else
self.imyou_nicknames.pluck(:name)
end
end
def remove_all_nicknames
self.imyou_nicknames.delete_all
end
def add_nickname(nickname)
if new_record?
self.imyou_nicknames.build(name: nickname)
else
self.imyou_nicknames.find_or_create_by(name: nickname)
end
end
def remove_nickname(nickname)
if new_record?
array = self.imyou_nicknames.to_a.delete_if do |imyou_nickname|
imyou_nickname.name == nickname
end
self.imyou_nicknames.replace(array)
else
self.imyou_nicknames.find_by(name: nickname)&.destroy!
end
true
end
def nicknames=(new_nicknames)
if new_record?
new_nicknames&.each do |new_nickname|
self.imyou_nicknames.build(name: new_nickname)
end
elsif new_nicknames.blank?
self.remove_all_nicknames
else
self.imyou_nicknames.where.not(name: new_nicknames).delete_all
new_nicknames.each do |new_nickname|
self.imyou_nicknames.find_or_create_by(name: new_nickname)
end
end
end
end
end
|