Class: AgileController
- Inherits:
-
AgileApplicationController
- Object
- ActionController::Base
- AgileApplicationController
- AgileController
- Defined in:
- app/controllers/agile_controller.rb
Overview
This is main controller for processing actions by AgileRails forms. It provides CRUD actions for editing database records. AgileRails does not require controller to be made for every table model but implements all actions in single controller. Logic required to control data entry is provided within AgileRails forms which are loaded dynamically for every action.
Data entry validations must therefore reside in document models definitions or can be implemented in forms. There are always validations that cannot be done in models. Like validations which include url parameters or accessing session variables. This is hard to be done in model therefore AgileRails controls had to be invented. AgileRails controls are modules with methods that are injected into agile controller and act in runtime like they are part of Agile controller.
Since Ruby and Rails provide some "automagic" loading of modules AgileRails controls must be saved into app/controls folder. Every model can have its own controls file. ar_page model's controls live in ar_page_controls.rb file. By convention module names are declared in camel case, so our ar_page_controls.rb declares ArPageControls module.
Controls (among other) may contain 8 callback methods. These methods are:
- before_new
- new_record
- dup_record
- before_edit
- before_save
- after_save
- before_delete
- after_delete
Methods before_new, before_edit, before_save or before_delete may also effect flow of the application. If method return false (not nil but FalseClass) normal flow of the program is interrupted and last operation is canceled.
Second control methods that can be declared in AgileRails controls are filters for viewing and sorting documents. It is often required that dynamic filters are applied to data_set documents.
data_set:
filter: current_users_documents
Example implemented controls method:
def current_users_documents
if agile_user_can(ArPermission::CAN_READ)
ArPage.where(created_by: session[:user_id])
else
flash[:error] = 'User can not perform this operation!'
false
end
end
If filter method returns false user will be presented with flash error.
Instance Method Summary collapse
-
#_filter ⇒ Object
Filter action.
-
#create ⇒ Object
Create (or duplicate) action.
-
#destroy ⇒ Object
Destroy action.
-
#duplicate_record(source) ⇒ Object
Will duplicate source document into new record.
-
#edit ⇒ Object
Edit action.
-
#index ⇒ Object
Index action.
-
#login ⇒ Object
Login action.
-
#logout ⇒ Object
Logout action.
-
#new ⇒ Object
New action.
-
#run ⇒ Object
Run action.
-
#set_development_site ⇒ Object
Shortcut for setting currently selected site in development.
-
#show ⇒ Object
Show displays record in readonly mode.
-
#update ⇒ Object
Update action.
Methods inherited from AgileApplicationController
#agile_dump, #agile_edit_mode?, #agile_get_site, #agile_process_default_request, #agile_render_404, #agile_user_has_role?, #agile_visit_log, find_help_file, #set_page_title
Instance Method Details
#_filter ⇒ Object
Filter action.
102 103 104 |
# File 'app/controllers/agile_controller.rb', line 102 def _filter index end |
#create ⇒ Object
Create (or duplicate) action.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'app/controllers/agile_controller.rb', line 214 def create # not authorized unless agile_user_can(ArPermission::CAN_CREATE) flash[:error] = t('agile.not_authorized') return index end # create document if params['id'].nil? # Prevent double form submit return index if double_form_submit? create_new_empty_record if save_data flash[:info] = t('agile.record_saved') params[:return_to] = 'index' if params[:commit] == t('agile.save&back') # save & back return process_return_to(params[:return_to]) if params[:return_to] @form_params['id'] = @record.id # must be set, for proper update link params[:id] = @record.id # must be set, for find_record edit else # error return process_return_to(params[:return_to]) if params[:return_to] render action: :new end else # duplicate record find_record new_record = duplicate_record(@record) create_new_empty_record(new_record) if (m = callback_method('dup_record')) then callback_method_call(m) end update_standards @record.save! index end end |
#destroy ⇒ Object
Destroy action. Used also for enabling and disabling record.
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'app/controllers/agile_controller.rb', line 300 def destroy find_record # check permission required to delete = if params['operation'].nil? if @record.respond_to?('created_by') # needs can_delete_all if created_by is present and not owner (@record.created_by == session[:user_id]) ? ArPermission::CAN_DELETE : ArPermission::CAN_DELETE_ALL else ArPermission::CAN_DELETE # by default end else # enable or disable record if @record.respond_to?('created_by') (@record.created_by == session[:user_id]) ? ArPermission::CAN_EDIT : ArPermission::CAN_EDIT_ALL else ArPermission::CAN_EDIT # by default end end ok2delete = agile_user_can() case # not authorized when !ok2delete then flash[:error] = t('agile.not_authorized') return index # delete document when params['operation'].nil? then # before_delete callback if (m = callback_method('before_delete') ) ret = callback_method_call(m) # don't do anything if return is false return index if ret.class == FalseClass end # take care of transaction begin transaction_begin() if @record.destroy save_journal(:delete) flash[:info] = t('agile.record_deleted') # after_delete callback if (m = callback_method('after_delete') ) callback_method_call(m) elsif params['after-delete'].to_s.match('return_to') params[:return_to] = params['after-delete'] end # Process return_to link if params[:return_to] transaction_end() return process_return_to(params[:return_to]) end else flash[:error] = (@record) transaction_abort('') end rescue Exception => e transaction_abort() transaction_end() logger.error(%(#{e.}\n\n#{e.backtrace.join("\n")})) return if Rails.env.test? # or test will fail raise end # end transaction normaly transaction_end() return index # deactivate document when params['operation'] == 'disable' then if @record.respond_to?('active') @record.active = false save_journal(:update, @record.changes) update_standards() @record.save flash[:info] = t('agile.record_disabled') end # reactivate document when params['operation'] == 'enable' then if @record.respond_to?('active') @record.active = true update_standards() save_journal(:update, @record.changes) @record.save flash[:info] = t('agile.record_enabled') end #TODO reorder documents when params['operation'] == 'reorder' then end @form_params['action'] = 'update' render action: :edit end |
#duplicate_record(source) ⇒ Object
Will duplicate source document into new record. This method is used for duplicating record and is subroutine of create action.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'app/controllers/agile_controller.rb', line 196 def duplicate_record(source) duplicates = params['dup_fields'].split(',').map(&:strip) dest = {} source.attribute_names.each do |attribute_name| next if attribute_name == 'id' # don't duplicate _id dest[attribute_name] = source[attribute_name] # if duplicate, string dup is added. For unique fields dest[attribute_name] += ' dup' if duplicates.include?(attribute_name) end dest['created_at'] = Time.now if dest['created_at'] dest['updated_at'] = Time.now if dest['updated_at'] dest end |
#edit ⇒ Object
Edit action.
254 255 256 257 258 259 260 261 262 263 |
# File 'app/controllers/agile_controller.rb', line 254 def edit find_record if (m = callback_method('before_edit') ) ret = callback_method_call(m) # don't do anything if return is false return index if ret.class == FalseClass end @form_params['action'] = 'update' render action: :edit end |
#index ⇒ Object
Index action
87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/controllers/agile_controller.rb', line 87 def index @form['index']['data_set'] ||= {} redirected = (@form['table'] == 'ar_memory' ? process_in_memory : process_data_set) return if redirected callback_method_call(@form.dig('index', 'data_set', 'footer') || 'update_footer') respond_to do |format| format.html { render action: :index } format.js { render partial: :result } end end |
#login ⇒ Object
Login action. Used to login direct to CMS. It is mostly used when first time creating site and when something goes so wrong, that common login procedure is not available.
Login can be called directly with url http://site.com/agile/login
130 131 132 133 134 135 |
# File 'app/controllers/agile_controller.rb', line 130 def login return set_development_site if params[:id] == 'test' session[:edit_mode] = 0 unless params[:ok] render action: 'login' end |
#logout ⇒ Object
Logout action. Used to logout direct from CMS.
Logout can be called directly with url http://site.com/agile/logout
142 143 144 145 146 147 |
# File 'app/controllers/agile_controller.rb', line 142 def logout session[:edit_mode] = 0 session[:user_id] = nil session[:user_roles] = nil render action: 'login' end |
#new ⇒ Object
New action.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'app/controllers/agile_controller.rb', line 171 def new flash[:error] = flash[:warning] = flash[:info] = nil # not authorized unless agile_user_can(ArPermission::CAN_CREATE) flash[:error] = t('agile.not_authorized') logger.error("******* #{t('agile.not_authorized')} #{session[:user_name]} #{AgileHelper.table_param(params)}") return index end create_new_empty_record() if (m = callback_method('before_new') ) ret = callback_method_call(m) return index if ret.class == FalseClass end load_initial_values() # new_record callback. Set default values for new record if (m = callback_method('new_record') ) then callback_method_call(m) end @form_params['action'] = 'create' end |
#run ⇒ Object
Run action
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'app/controllers/agile_controller.rb', line 398 def run # determine control file name and method control_name, method_name = params[:control].split('.') if method_name.nil? method_name = control_name control_name = AgileHelper.table_param(params) end # extend with control methods extend_with_control_module(control_name) if respond_to?(method_name) # can it be called return return_run_error t('agile.not_authorized') unless can_process_run # call method respond_to do |format| format.json { send method_name } format.html { send method_name } end else # Error message return_run_error "Method #{method_name} not defined in #{control_name}_control" end end |
#set_development_site ⇒ Object
Shortcut for setting currently selected site in development. Will search for ar_site document with site name 'development' and set alias_for to site url parameter.
154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'app/controllers/agile_controller.rb', line 154 def set_development_site # only in development return agile_render_404 unless Rails.env.development? alias_site = ArSite.find_by(name: params[:site]) return agile_render_404 unless alias_site # update alias for site = ArSite.find_by(name: 'development') site.alias_for = params[:site] site.save redirect_to '/' end |
#show ⇒ Object
Show displays record in readonly mode.
109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'app/controllers/agile_controller.rb', line 109 def show find_record # before_show callback if (m = callback_method('before_show') ) ret = callback_method_call(m) if ret.class == FalseClass @form['readonly'] = nil # must be return index end end render action: 'edit' end |
#update ⇒ Object
Update action.
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'app/controllers/agile_controller.rb', line 268 def update find_record # check if record was not updated in mean time if @record.respond_to?(:updated_at) if params[:last_updated_at].to_i != @record.updated_at.to_i flash[:error] = t('agile.updated_by_other') return render(action: :edit) end end if agile_user_can(ArPermission::CAN_EDIT_ALL) || (@record.respond_to?('created_by') && @record.created_by == session[:user_id] && agile_user_can(ArPermission::CAN_EDIT)) if save_data params[:return_to] = 'index' if params[:commit] == t('agile.save&back') # save & back @form_params['action'] = 'update' # Process return_to return process_return_to(params[:return_to]) if params[:return_to] else # do not forget before_edit callback if m = callback_method('before_edit') then callback_method_call(m) end return render action: :edit end else flash[:error] = t('agile.not_authorized') end edit end |