diff --git a/app/controllers/default/units_controller.rb b/app/controllers/default/units_controller.rb index 9ca24a7..e6dd2ed 100644 --- a/app/controllers/default/units_controller.rb +++ b/app/controllers/default/units_controller.rb @@ -1,16 +1,13 @@ class Default::UnitsController < ApplicationController navigation_tab :units - before_action -> { find_unit(current_user) }, only: :export - before_action -> { find_unit(nil) }, only: [:import, :destroy] + before_action :find_unit, only: [:import, :export, :destroy] - before_action except: :index do - case action_name.to_sym - when :import, :import_all - raise AccessForbidden unless current_user.at_least(:active) - else - raise AccessForbidden unless current_user.at_least(:admin) - end + before_action only: :import do + raise AccessForbidden unless current_user.at_least(:active) + end + before_action except: [:index, :import] do + raise AccessForbidden unless current_user.at_least(:admin) end def index @@ -18,20 +15,19 @@ class Default::UnitsController < ApplicationController end def import - params = @unit.slice(Unit::ATTRIBUTES - [:symbol, :base_id]) - current_user.units - .find_or_initialize_by(symbol: @unit.symbol) - .update!(base: @base, **params) + raise ParameterInvalid unless @unit.default? && @unit.port(current_user) run_and_render :index end - def import_all + #def import_all # From defaults_diff return not only portability, but reason for not being # portable: missing_base and nesting_too_deep. Add portable and # missing_base, if possible in one query - end + #end def export + raise ParameterInvalid unless !@unit.default? && @unit.port(nil) + run_and_render :index end def destroy @@ -39,8 +35,7 @@ class Default::UnitsController < ApplicationController private - def find_unit(user) - @unit = Unit.find_by!(id: params[:id], user: user) - @base = Unit.find_by!(symbol: @unit.base.symbol, user: user ? nil : current_user) if @unit.base + def find_unit + @unit = Unit.find_by!(id: params[:id], user: [current_user, nil]) end end diff --git a/app/models/unit.rb b/app/models/unit.rb index de362aa..82fcd7f 100644 --- a/app/models/unit.rb +++ b/app/models/unit.rb @@ -24,6 +24,8 @@ class Unit < ApplicationRecord other_bases_units = arel_table.alias('other_bases_units') sub_units = arel_table.alias('sub_units') + # TODO: move inner 'with' CTE to outer 'with recursive' - it can have multiple + # CTEs, even non recursive ones. Unit.with_recursive(actionable_units: [ Unit.with(units: self.or(Unit.defaults)).left_joins(:base) .where.not( @@ -90,7 +92,11 @@ class Unit < ApplicationRecord user_id.nil? end - def exportable? - !default? && (base.nil? || base.default?) + def port(recipient) + recipient_base = base && Unit.find_by(symbol: base.symbol, user: recipient) + return nil if recipient_base.nil? != base.nil? + params = slice(ATTRIBUTES - [:symbol, :base_id]) + Unit.find_or_initialize_by(user: recipient, symbol: symbol) + .update(base: recipient_base, **params) end end diff --git a/config/routes.rb b/config/routes.rb index 06c1241..b62b98d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,7 +9,7 @@ Rails.application.routes.draw do namespace :default do resources :units, only: [:index, :destroy] do member { post :import, :export } - collection { post :import_all } + #collection { post :import_all } end end