forked from fixin.me/fixin.me
Fix SQLite query compatibility inside WITH clause
SQLite3::SQLException: circular reference
This commit is contained in:
@@ -77,15 +77,13 @@ class Unit < ApplicationRecord
|
|||||||
.from(units).group(:base_id, :symbol)
|
.from(units).group(:base_id, :symbol)
|
||||||
}
|
}
|
||||||
scope :ordered, ->{
|
scope :ordered, ->{
|
||||||
left_outer_joins(:base).order(ordering)
|
left_outer_joins(:base).order([
|
||||||
}
|
arel_table.coalesce(Arel::Table.new(:bases_units)[:symbol], arel_table[:symbol]),
|
||||||
|
|
||||||
def self.ordering
|
|
||||||
[arel_table.coalesce(Arel::Table.new(:bases_units)[:symbol], arel_table[:symbol]),
|
|
||||||
arel_table[:base_id].not_eq(nil),
|
arel_table[:base_id].not_eq(nil),
|
||||||
:multiplier,
|
arel_table[:multiplier],
|
||||||
:symbol]
|
arel_table[:symbol]
|
||||||
end
|
])
|
||||||
|
}
|
||||||
|
|
||||||
before_destroy do
|
before_destroy do
|
||||||
# TODO: disallow destruction if any object depends on this unit
|
# TODO: disallow destruction if any object depends on this unit
|
||||||
@@ -114,11 +112,11 @@ class Unit < ApplicationRecord
|
|||||||
|
|
||||||
def successive
|
def successive
|
||||||
units = Unit.arel_table
|
units = Unit.arel_table
|
||||||
lead = Arel::Nodes::NamedFunction.new('LAG', [units[:id]])
|
Unit.with(units_with_lag: user.units.left_outer_joins(:base).select(
|
||||||
window = Arel::Nodes::Window.new.order(*Unit.ordering)
|
units[Arel.star],
|
||||||
lag_id = lead.over(window).as('lag_id')
|
Arel::Nodes::NamedFunction.new('LAG', [units[:id]])
|
||||||
Unit.with(
|
.over(Arel::Nodes::Window.new.order(Unit.ordered.order_values)).as('lag_id')
|
||||||
units: user.units.left_outer_joins(:base).select(units[Arel.star], lag_id)
|
)).from(Arel::Table.new(:units_with_lag).as(:units))
|
||||||
).where(units[:lag_id].eq(id)).first
|
.where(units[:lag_id].eq(id)).take
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -74,6 +74,30 @@ class UnitsTest < ApplicationSystemTestCase
|
|||||||
assert_equal values, Unit.last.attributes.slice(*values.keys)
|
assert_equal values, Unit.last.attributes.slice(*values.keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "create updates view in order" do
|
||||||
|
# Destroy and re-create unit to verify its index position is unchanged.
|
||||||
|
sign_in(user: users.select { |u| u.confirmed? && u.units.many? }.sample)
|
||||||
|
|
||||||
|
link = all(:link_or_button, exact_text: t('units.unit.destroy')).sample
|
||||||
|
symbol = link.ancestor('tr').first(:link).text
|
||||||
|
index = link.ancestor('tbody').all('tr').index { |e| e.first(:link).text == symbol }
|
||||||
|
unit = @user.units.find_by(symbol: symbol)
|
||||||
|
|
||||||
|
link.click
|
||||||
|
if unit.base_id?
|
||||||
|
find_link(unit.base.symbol).ancestor('tr').click_on(t('units.unit.new_subunit'))
|
||||||
|
fill_in 'unit[multiplier]', with: unit.multiplier
|
||||||
|
else
|
||||||
|
click_on t('units.index.new_unit')
|
||||||
|
end
|
||||||
|
fill_in 'unit[symbol]', with: unit.symbol
|
||||||
|
click_on t('helpers.submit.create')
|
||||||
|
|
||||||
|
within "tbody > tr:nth-child(#{index+1})" do
|
||||||
|
assert_selector :link, exact_text: symbol
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "new and edit on validation error" do
|
test "new and edit on validation error" do
|
||||||
# It's not possible to cause validation error on :edit with single unit
|
# It's not possible to cause validation error on :edit with single unit
|
||||||
LINK_LABELS.delete(:edit) unless @user.units.count > 1
|
LINK_LABELS.delete(:edit) unless @user.units.count > 1
|
||||||
|
|||||||
@@ -35,6 +35,67 @@ class ActiveSupport::TestCase
|
|||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Range based string generation. Not finished, but saved as a potential
|
||||||
|
# reference for future work. To work properly it needs to sort in collation
|
||||||
|
# order of database.
|
||||||
|
#def random_between(from, to, maxlength)
|
||||||
|
# # TODO: sort UNICODE_CHARS
|
||||||
|
# byebug
|
||||||
|
# result = ''
|
||||||
|
# maxlength.times do |i|
|
||||||
|
# case
|
||||||
|
# when from[i] == to[i]
|
||||||
|
# result += from[i]
|
||||||
|
# else
|
||||||
|
# from_index = UNICODE_CHARS.bsearch_index(from[i] || UNICODE_CHARS[0])
|
||||||
|
# to_index = UNICODE_CHARS.bsearch_index(to[i])
|
||||||
|
# index = rand(from_index..to_index)
|
||||||
|
# case
|
||||||
|
# when index == from_index
|
||||||
|
# result += UNICODE_CHARS[index]
|
||||||
|
# from[i+1..].each_char do |c|
|
||||||
|
# from_index = UNICODE_CHARS.bsearch_index(from[i])
|
||||||
|
# index = rand(from_index..UNICODE_CHARS.length-1)
|
||||||
|
# result += UNICODE_CHARS[index]
|
||||||
|
# break if index != from_index
|
||||||
|
# end
|
||||||
|
# if result == from
|
||||||
|
# if result.length < maxlength
|
||||||
|
# result += UNICODE_CHARS.sample
|
||||||
|
# else
|
||||||
|
# # TODO: succ result[i..]
|
||||||
|
# # raise if result == to
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# break
|
||||||
|
# when index == to_index
|
||||||
|
# result += UNICODE_CHARS[index]
|
||||||
|
# to[i+1..].each_char do |c|
|
||||||
|
# to_index = UNICODE_CHARS.bsearch_index(to[i])
|
||||||
|
# index = rand(-1..to_index)
|
||||||
|
# break if index == -1
|
||||||
|
# result += UNICODE_CHARS[index]
|
||||||
|
# break if index != to_index
|
||||||
|
# end
|
||||||
|
# if result == to
|
||||||
|
# if result.length > i+1
|
||||||
|
# result = result[..-2]
|
||||||
|
# else
|
||||||
|
# # TODO: prev result[i..]
|
||||||
|
# # raise if result == from
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# break
|
||||||
|
# else
|
||||||
|
# result += UNICODE_CHARS[index]
|
||||||
|
# break
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# return result += UNICODE_CHARS.sample(rand(0..maxlength-i-1)).join
|
||||||
|
# # if result == from/to ...
|
||||||
|
#end
|
||||||
|
|
||||||
def deep_rand(*args)
|
def deep_rand(*args)
|
||||||
case args
|
case args
|
||||||
when Array
|
when Array
|
||||||
|
|||||||
Reference in New Issue
Block a user