Skip to content

Conversation

@ofedoren
Copy link
Member

@ofedoren ofedoren commented Nov 20, 2024

This is an alternative for #10368, tries to make ordering by columns, which are not part of actual table, possible.

This PR enables it for roles model, making possible to click on locked column in roles index page and see the ordering, as well as doing so via API.

Added an entry for developer_docs saying how to use it within plugins.

Thanks, @adamruzicka, for the idea!

@MariaAga, what do you think?

P.S. The only issue I see is that we'd need to update https://github.com/theforeman/foreman-tasks/blob/master/app/controllers/foreman_tasks/api/tasks_controller.rb#L195 to be compatible. Could be done as part of removal deprecated stuff.

@MariaAga
Copy link
Member

It seems to work as expected in ui and api, the code makes sense but I think we need a Ruby person to verify it, @adamruzicka ?

Copy link
Contributor

@adamruzicka adamruzicka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable, left two comments. Could we also get a related patch in one of the plugins where its needed?

if virt_column.blank? || model_of_controller.columns_hash[virt_column] || !base_scope.respond_to?(select_method)
base_scope.search_for(params[:search], :order => params[:order]).paginate(:page => params[:page], :per_page => params[:per_page])
else
base_scope.send(select_method).search_for(params[:search]).order(params[:order]).paginate(:page => params[:page], :per_page => params[:per_page])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI does not accept per_page being set to all?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, thinking out loud, from the name I wouldn't really expect it to deal with pagination and so on, but that might be just me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI does not accept per_page being set to all?

Nope, otherwise we'd have a button suggesting that.

Also, thinking out loud, from the name I wouldn't really expect it to deal with pagination and so on, but that might be just me

Naming is hard, any suggestion is more than welcome 🍪

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this break per_page=all for api?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this break per_page=all for api?

wrap_for_virt_column_select method is only for UI controllers, thus no.

API controllers most (if not all) of the time use resource_scope_for_index method, which is overridden in this PR:
https://github.com/theforeman/foreman/pull/10381/files#diff-f97adc72a387ed049f1b789f93f9d5c592f481e9e37c6fb75eabfcc2f36d467eR172

This override should not affect per_page=all, since it's either uses super to use old behavior or explicitly deals with it in https://github.com/theforeman/foreman/pull/10381/files#diff-f97adc72a387ed049f1b789f93f9d5c592f481e9e37c6fb75eabfcc2f36d467eR181.

@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from 56d9b7a to 373036f Compare November 22, 2024 11:51
@ofedoren ofedoren marked this pull request as draft November 28, 2024 16:38
@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from 373036f to 0039511 Compare November 29, 2024 15:29
@ofedoren ofedoren marked this pull request as ready for review November 29, 2024 15:29
@ofedoren
Copy link
Member Author

ofedoren commented Nov 29, 2024

I've updated the logic a bit: since most of the UI controllers use resource_base_search_and_page/resource_base_with_search, I updated this method, so the new wrap_for_virt_column_select method is not necessary, but rather an optional helper. Although, looking at the changes in theforeman/foreman_openscap#587, I don't think this wrapper will be used...

WDYT? Should we expose the wrapper or rather force usage of already defined loaders if ordering by virt columns desired?

@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from 0039511 to 4fea540 Compare December 2, 2024 14:12
@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from 4fea540 to dfc8198 Compare January 17, 2025 14:33
@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from dfc8198 to b0ae94f Compare July 31, 2025 13:03
@ofedoren
Copy link
Member Author

@adamruzicka, @MariaAga, reviving this one: do we still want that?

Note: it also fixes broken ordering by locked on roles page.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds the ability to order by virtual columns in Foreman, specifically enabling ordering by the "locked" column in the roles model. This addresses issue #38024 by allowing users to sort roles by their locked status both in the UI and API.

  • Implements virtual column ordering support in both UI and API controllers
  • Adds a select_locked scope to the Role model to define the virtual "locked" column
  • Updates roles controller to use the new ordering functionality

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
app/models/role.rb Adds select_locked scope to define the virtual locked column
app/controllers/roles_controller.rb Updates to use resource_base_search_and_page for virtual column support
app/controllers/application_controller.rb Implements core virtual column ordering logic in resource_base_with_search
app/controllers/api/v2/base_controller.rb Adds virtual column ordering support to API controllers
test/controllers/roles_controller_test.rb Adds test for UI ordering by locked column
test/controllers/api/v2/roles_controller_test.rb Adds comprehensive tests for API ordering by locked column
developer_docs/how_to_create_a_plugin.asciidoc Documents how to implement virtual column ordering in plugins

Comment on lines 236 to 239
select_method = "select_#{virt_column}"
if virt_column.blank? || model_of_controller.columns_hash[virt_column] || !resource_base.respond_to?(select_method)
resource_base.search_for(params[:search], :order => params[:order])
else
Copy link

Copilot AI Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using send with user-controlled input (select_method derived from params[:order]) could be a security risk. Consider using a whitelist approach or validating the method name against allowed virtual columns.

Suggested change
select_method = "select_#{virt_column}"
if virt_column.blank? || model_of_controller.columns_hash[virt_column] || !resource_base.respond_to?(select_method)
resource_base.search_for(params[:search], :order => params[:order])
else
allowed_virtual_columns = %w[column1 column2 column3] # Replace with actual allowed column names
if virt_column.blank? || model_of_controller.columns_hash[virt_column] || !allowed_virtual_columns.include?(virt_column)
resource_base.search_for(params[:search], :order => params[:order])
else
select_method = "select_#{virt_column}"

Copilot uses AI. Check for mistakes.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied as 3776040.

@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from b0ae94f to b548dc4 Compare August 1, 2025 13:06
Comment on lines 173 to 177
virt_column = extract_virtual_column
select_method = "select_#{virt_column}"
scope = resource_scope(...)

if virt_column.blank? || resource_class.columns_hash[virt_column] || !scope.virtual_column_scopes.include?(select_method.to_sym)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have this pattern with small differences in three different places, could we make it dryer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. It indeed looks better now.

@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch 2 times, most recently from 3187f17 to c6ff412 Compare August 5, 2025 14:49
@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from c6ff412 to a5c1ede Compare September 25, 2025 11:11
@adamruzicka
Copy link
Contributor

/packit build

@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from a5c1ede to 85e3145 Compare September 30, 2025 14:05
model = respond_to?(:model_of_controller) ? model_of_controller : resource_class
return if virt_column.blank? || model.columns_hash[virt_column] || !base_scope.virtual_column_scopes.include?(select_method.to_sym)
base_scope.public_send(select_method).search_for(params[:search]).order(params[:order])
base_scope.public_send(select_method).search_for(params[:search]).reorder(params[:order])
Copy link
Member Author

@ofedoren ofedoren Sep 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This already considers unless params[:order].blank? since if it's empty the method returns earlier and the logic returns to the previous (current) state ignoring virtual column.

@adamruzicka
Copy link
Contributor

Could you rebase please?

@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from 85e3145 to b8c69f6 Compare October 2, 2025 12:30
Copy link
Contributor

@adamruzicka adamruzicka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested together with the foreman_openscap PR, works well

@adamruzicka
Copy link
Contributor

Could you please squash the commits?

Refs #38024 - Check if select_virt_col is allowed

Refs #38024 - Refactor the same logic

Refs #38024 - Reorder in case default scope with order
@ofedoren ofedoren force-pushed the feat-38024-allow-virt-ordering branch from b8c69f6 to 80dfd83 Compare October 2, 2025 12:57
@ofedoren
Copy link
Member Author

ofedoren commented Oct 2, 2025

Thanks, @adamruzicka, rebased / squashed. Although I'd like to see green tests just in case, but I don't think there will be related failures anyway 🤷

@ofedoren
Copy link
Member Author

ofedoren commented Oct 2, 2025

🍏

@adamruzicka adamruzicka merged commit bf4c6af into theforeman:develop Oct 2, 2025
56 checks passed
@adamruzicka
Copy link
Contributor

Thank you @ofedoren !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants