-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Sort / Search column syntax deprecation considerations #119
Comments
Hi @aldefouw, Glad to know the gem is of help to you and your team :) About the functionality you mention... here's what's been done on that front:
So, you've got nothing to worry about losing this functionality :) Now, about what are the things coming to a newer release? well:
This last feature has just been merged, and it represents a major surgery in the gem internals, which lead to breaking the build entirely. The gem works, but all tests need to be re-written, I have to find the time. You are welcome to try this branch in a sample pet app, to get a hold of the new syntax. Before I finish, I'd like to comment on the
part of your message. I will be glad and humbled if you'd be interested in getting involved in planning, developing, features addressing edge scenarios :) So, my question to you is, would you be interested in helping shape this gem's API and functionality? |
Hi Antonio - Thanks for your response. I apologize for the delay in getting back to you. It's been a busy week here since Monday was a federal holiday, and we're trying to fit a week's worth of work into 4 days. I appreciate your explanation and reassurance that the alias functionality will not be removed in the future. That makes us breathe a bit easier. With regard to your offer to be involved in the direction that the gem is headed, thank you very much for the offer. That is very kind. I think there's a strong possibility that we could continue to help report issues we run into. That said, we have dozens of projects that we work on for the department we are part of, and we only use DataTables in a few of them - many applications we work on are legacy PHP applications. So I'm not sure how frequent our feedback would be for you; but, we're happy to contribute when we can! With regard to the updates to the branch on v0-4-0, I'm curious how those changes would impact our current code. It looks like there may be significant changes to our code because of how we're using it. In particular, the changes to the sorting and searching methods - where they are consolidated into view_columns may be problematic. That's probably just for how we are using it though ... Below is a README that I wrote up for adding new datatables to our application. We dynamically set column names and decide whether we are going to sort or search on a column within the hash for that column that we've defined. It's more complicated than most people have, but it enables us to keep our JavaScript code very tidy. We have somewhere in the neighborhood of 50 separate DataTables but it only requires one call in Javascript because we're using Ruby to generate all of the Javascript we need for the different column parameters and such. Below is a README that I created for the project so other developers can add to our project. Unfortunately, I can't point you to a repository that includes our project because it isn't open source, but this should give you an idea of how our unique situation is structured. Perhaps some of these aspects could be handled more gracefully on the Gem level, but I wasn't really sure how to approach it on that level. Perhaps this will give you ideas if nothing else. Readme for our specific project integrationThe instructions below will cover how to
The general purpose of this document is to cover the basics of implementing a DataTable in our project. There isn't much code involved, but there are some important aspects to understand before diving in. Basic FactsMost of the code needed to create or modify DataTables Filters is contained within the /app/datatables folder. Model methods will need to be created in the respective model file (e.g. Award models in /app/models/award.rb). Helper methods should be placed in the respective helper file (e.g. Award helpers in /app/datatables/filters/award/award_helpers.rb). Methods that are common to all datatables are located in /app/datatables/common_datatables.rb. Create a Specific FilterThese instructions will demonstrate how to add a Specific Filter to Award. Although these instructions focus on 'Award', for Notes or Project, it is the same process - just use 'notes' or 'project' instead of 'award'. Note: This example is under the assumption we are creating an Award filter called FooBar. What are the requirements for a Specific Filter to work?Specific Filters have three requirements to make them work:
What exactly is a Specific Filter?A Specific Filter is essentially the specific implementation of a DataTable (which is defined within a Base Filter). Specific Filters are accessible through a route that you can type into your web browser. Each section (Award, Project, Notes) uses a standard view implementation, and each Specific Filter utilizes this view implementation without any extra code necessary. (For instance, you can see the Award view implementation used for all Specific Filters in /app/views/awards/index.html.erb.) Naming conventions help everything come together. Implementation of FooBar Specific Filter using DefaultAwardFilter Base Filter
* Base Filter does not have to be DefaultAwardFilter as you will see in the next section ().As you can see, the Query Method name for a given filter needs to match the Route name. ALWAYS. If they do not, your implementation will not work. Additionally, the Specific Filter filename (i.e. award_foo_bar_filter) will ALWAYS be "sandwiched" between "award" and "filter" in the Class name and the filename. These requirements will make more sense as you step through the tutorial. #1 - Create a method in /app/models/award.rb called foo_bardef self.foo_bar(inputs)
entire(inputs)
end You need to fill the method with whatever Award data you want in the DataTable. Since we are going to inherit from DefaultAwardFilter, the entire method is a good choice. #2 - Create a route for this filter in the following file: /config/initializers/constants.rbRoutes are dynamically created for Awards (using the values in AWARD_FILTERS). The same is true for Project or Notes - they just use PROJECT_FILTERS and NOTE_FILTERS, respectively. #3 - Add foo_bar to the AWARD_FILTERS array in /config/initializers/constants.rbThis text addition will enable a route located at /awards/foo_bar AWARD_FILTERS = %w(
foo_bar
budget_balance_overdrawn
budget_balance_overdrawn_cl
budget_balance_overdrawn_grant
...
) NOTE : Don't copy and paste the above code. It will break other routes. Add foo_bar to the top of the existing array list. #4 - Create a file called award_foo_bar_filter.rb in this folder: /app/datatables/filters/award/specific_filters/This file serves one purpose: To tell Ruby what Base Filter your Specific Filter inherits from. Your filter will currently inherit from the DefaultAwardFilter Base Filter. Since DefaultAwardFilter is already in place by default, all we need to do is reference it in our file. (The next section covers how to ... ) #4 - Add your class definition to award_foo_bar_filter.rbUse the following code (and save) in the file: class AwardFooBarFilter < DefaultAwardFilter
end #5 - Test your FooBar filterAt this point, you should have a new Specific Filter implementation of the DefaultAwardFilter (Base Filter) . http://localhost:3000/awards/foo_bar Since DefaultAwardFilter is also used in other Specific Filter implementations, you should see the same content as http://localhost:3000/awards. If you do not, you may want to review the steps above. IMPORTANT NOTE: All Specific Filters MUST inherit from a Base Filter. Create a Base FilterThis tutorial assumes that you've already completed the Create a Specific Filter tutorial. This tutorial is dependent upon those files being in place. Please complete before proceeding. Why use Base and Specific Filter hierarchies?The idea behind the Base and Specific Filter hierarchy is that Specific Filters inherit functionality from common Base Filters located in each section (Award, Project, Notes). The reason that Specific Filters inherit from Base Filters is simple: Base Filters follow the DRY principle by allowing us to define the columns of a DataTable one time for use in several different Specific Filters. This promotes re-use and keeps code to a minimum. Implementation of FooBar Specific Filter using FooNorf Base Filter
The only real difference we are going to see in this tutorial versus the first tutorial is that the Base Filter will be different. The steps below cover how to create the new Base Filter called FooNorf. #1 - Add the FooNorf Base Filtera. Go to /app/datatables/filters/award/base_filters. class FooNorfFilter < DefaultAwardFilter
def define_columns
[
:col_1,
:col_2,
:col_3
]
end
end NOTE: In this example, FooNorfFilter inherits from DefaultAwardFilter. If there was a different Base Filter you would prefer to inherit from, you could specify that in place of DefaultAwardFilter in the code. #2 - Learn about column definitions in Award Headers and Bodya. Open /app/datatables/filters/award/award_headers_and_body.rb. b. Each column (i.e. col_1, col_2, col_3) that you define in the define_columns method (see the first step) needs instructions for how it will be displayed. Each column has two components:
The column's Header contains an attributes hash that describes the column header. Below are the valid attributes that the Header hash accepts.
#3 - The column's Body contains the content that will be displayed in each row of the DataTable for that column.#4 - Add the code below to /app/datatables/filters/award/award_headers_and_body.rb.This code will add Header and Body definitions for the three columns that are specified in your Base Filter definition in the first step: # === COL 1 === #
def col_1_header
{
header: "Award Type",
col: 'Award.award_type',
export: true,
sort: true,
search: true
}
end
def col_1_body(award)
award.award_type
end
# === COL 2 === #
def col_2_header
{
header: "Sponsor Name",
col: 'Award.award_sponsor_name',
export: true,
sort: true,
search: true
}
end
def col_2_body(award)
award.award_sponsor_name
end
# === COL 3 === #
def col_3_header
{
header: "Primary PI Name",
col: 'Award.award_primary_pi_name',
export: true,
sort: true,
search: true
}
end
def col_3_body(award)
award.award_primary_pi_name
end #5 - Change the Base Filter that your FooBar Specific Filter inherits from.
#6 - Test your FooBar filter.Visit http://localhost:3000/awards/foo_bar At this point, you should see columns labeled Award Type, Sponsor Name, and Primary PI Name in your FooBar filter. You should also see rows of data in each column. Additionally, you should be able to sort and search on any of the 3 fields. Finally, all three columns should be exportable to PDF or CSV. If you don't see these items, retrace your steps and see where things went wrong. |
@aldefouw It seems you concept is quite difficult, I dont know what type of project you have but its to hard define datatable in you senario. can you please look at this sample(https://github.com/ajahongir/ajax-datatables-rails-v-0-4-0-how-to) project and tell is this way acceptable for you? |
Sure - I will check it out! It might be a few days though - I have a busy week ahead of me. |
@antillas21 I'm testing the new v-0-4-0 branch. It's working quite well except what it seems to be a bug in search. But now I have an objection : I'm not sure that passing the searchable value (yes|no) by view params is a good idea for security reasons. To be honest, at first I thought the searchable boolean was set in
IMHO it would be more logical to set searchable/orderable settings here. |
@n-rodriguez Its good argument. I agree with security reasons. May be it will much better to define def view_columns
@view_columns ||= [
{ source: 'User.id', searchable: false },
{ source: 'User.first_name' },
{ source: 'User.last_name' },
{ source: 'User.email' },
]
end def searchable?
@view_column[:searchable] || options[:orderable] == 'true'
end |
For people who want to manage this param from the view, yes. I'm gonna try it. |
@antillas21 - Unfortunately, the other projects I am working on are consuming all of my time at work. I want to look at the branch for you - just haven't had the time yet. Getting pulled in multiple directions on many things. At the worst, we can just lock down our version in our Gemfile and continue using the version we are using now. We have such a specific need in our datatables that it might not be easy to maintain compatibility moving forward. |
@antillas21 I've done some tests and it doesn't work :
Because
and
which doesn't solve the issue. |
@n-rodriguez if you declare columns attributes in your jQuery(document).ready(function() {
$('#users-table').dataTable({
processing: true,
serverSide: true,
ajax: $('#users-table').data('source'),
pagingType: "full_numbers",
columns: [
{ searchable: true, sortable: false },
{ searchable: false, sortable: false },
{ searchable: true, sortable: true }
]
});
}); passing By default, like you said, all columns are both sortable and searchable... but you can override this behavior 😉 |
@aldefouw No worries, contributing to open source is always like that, trust me... I have some ideas for this library, just need to find the time between the projects I'm currently working on. That being said, whenever you have a time and if you're still interested in contributing a solution, I will be grateful and willing to take a look at your proposed changes 😄 |
Yep, I've updated my post |
So if I'm reading this right, support for aliased tables or columns is going to come back? Currently in |
+1 for mcnelson |
Hi there! Any news? |
is there an update on this? I need to be able to use custom aliased join tables. not just ActiveRecord Constants in my view columns |
currently
ALL throw an error |
@SampsonCrowley |
I'm closing this issue since most of it is implemented in v0.4 and the rest (filters, etc) seems too complex to be done for now. I'm more in favor of stabilizing the API (see #288) and reducing coupling so the gem could be used elsewhere than adding new features. @SampsonCrowley : feel free to open a new issue if it's still not working |
@n-rodriguez it sort of does. I had to add custom |
yeah, it's fixed :) cb8a3da |
great :) |
Hello -
First off - huge thanks to you for maintaining this gem, Antonio. This gem has made life a lot easier for a project the team I'm a part of is working on.
What I'd like to know is what the plan is for for the sort and search column syntax moving forward. I know that the
table_name.column_name
is already deprecated - but are you planning to remove it entirely in future versions?I for one would not be in favor of fully removing it and I will likely have to fork updates if that happens.
I knew going into the newer version of this gem (0.3.0) that this functionality was deprecated, but we continue to use the
table_name.column_name
functionality because ModelName.attribute will not work for us in one of our specific situations.To be more specific, in our case - we don't use
table_name.column name
- we actually use justcolumn_name
because we're calling an alias.Our query being made contains a database column alias we formed in the SELECT clause that we use to sort the columns in our DataTable.
We know that a column alias is "ugly" code and it's stepping outside of the model - which isn't a good practice typically. However, in this case, we are trying to sort on a piece of data that is more complex than a single column can typically contain - so it requires a nested sub-query inside an SQL column alias.
I know that this is a bit of an edge case, but I'm wondering if you might consider a configuration option where it would allow us to run in a legacy mode that would prevent these deprecation warnings from happening.
Or perhaps you might consider allowing the legacy column types (including aliases) to be in the column as an option, if configured ...
These are just thoughts. If there is a more elegant way to handle this edge case, I'm all ears.
We know that the functionality is deprecated, but in the case of needing to reference an alias to sort a column properly, there currently really isn't any other choice for us that I'm aware of.
Any insights or thoughts on this area would be appreciated. I've walked through part of this gem's code a few times to see what's happening, but I'm sure you have additional insights beyond what I can glean by reading through.
Thank you!
The text was updated successfully, but these errors were encountered: