Similar topic to my last post, but a different brand of methods. In particular, the url_for and link_to methods have come to bother me at times. I will mention one instance in particular: I am designing a high-end administrative interface. This interface supports paging, sorting and limiting to specific field values. Thus I have params named page, sort and limit. The lack of elegance I see comes when I make new links or add new parameters. To keep the administrator on the same page time and time again, I have to add ":page => params[:page]" to every link in my scaffold''s edit.rhtml, list.rhtml and new.rhtml as well as to my helpers that generate paging, sorting and limiting links. As I add more parameters, the link_to commands in these files grow more and more unreadable and the number of places I have to explicitly specify every parameter in the query string increases. I attempted to use :overwrite_params, but then all of a sudden link_to does not seem to recognize my routes. It starts dumping URL-defined params into the query string. When I read about link_to, the description said that it intuitively understood the hierarchy of parameters. If the :action changed, the :id was nulled. If the :controller changed, :action and :id were nulled. And so forth. The problem is once you get into params in the query string such as params[:page]. It seems to me that a link_to specifying only :sort => sort should not overwrite :page or :limit. Params in the query string should act as brothers. No one param should be the parent of another; setting one should not unset the others. They are not in a hierarchy. They merely exist side-by-side. Changing the way rails nulls query string parameters would keep those params out of my paging, sorting and limiting helpers, which I feel should ideally not have to know about each other. And if there is some reason this should not be the default, perhaps it should at least be an option. Or perhaps :overwrite_params needs to be fixed. Or perhaps I am using it incorrectly? This also wouldn''t address every repeated instance of ":page => params[:page]" in my views. Changing :action still needs to null query string parameters. Or does it? Should query string parameters be considered children of even :action or :controller? Is :page necessarily subordinate to :action => ''list''? To me it seems :page should be subordinate to the :controller but not the action. Perhaps some method of explicitly specifying query string parameter hierarchies is in order. -- Posted via http://www.ruby-forum.com/.
Francois Beausoleil
2006-Apr-25 17:30 UTC
[Rails] Does Rails need more useful URL helpers?
Hello Stephen, 2006/4/25, Stephen Friedman <sfriedman@tortus.com>:> I am designing a high-end administrative interface. This interface > supports paging, sorting and limiting to specific field values. Thus I > have params named page, sort and limit.I see your point. The way I coded around that is to store the page, sort and limit in the session. If the incoming request has those parameters, I overwrite the session, else I use the session''s values. Here''s how I do it: class UsersController < ApplicationController before_filter :process_filters def index @users, @user_pages = paginate(:users, :limit => @limit, :page => @page, :order => @sort) end def process_filters # That generates a namespace for the common parameters session[self.name] ||= Hash.new @page = params[:page] || session[self.name][:page] || 1 session[self.name][:page] = @page # Same kind of code for limit and order/sort end end Hope that helps ! -- Fran?ois Beausoleil http://blog.teksol.info/
Stephen Friedman
2006-Apr-26 14:08 UTC
[Rails] Re: Does Rails need more useful URL helpers?
That''s definitely a very nice solution! Obviously it breaks down when users do not have cookies enabled. In the case of an administrative panel, we are free to require our customer to enable cookies. For the similar public environment to come, this solution would become less desirable. One thought, though: why use the params array at all? Why not just leave the variables in the session? The default paginator looks for its page number in the params variable, but I believe you can roll-your-own Paginator and tell it to use the session variable: @element_count = Element.count (or count_by_sql or parent.element.count as needed) @element_pages = Paginator.new self, @element_count, 20, @session[self.name][:page] I haven''t actually tried this, though I assume it''d work fine. I had to generate my own paginators for this same administrative panel because I designed it to operate both with and without a limiting id at each descent into the hierarchy. This complicated matters and forced me to use my own paginator, but the benefits were definitely worth it, and doing so is hardly difficult. -- Posted via http://www.ruby-forum.com/.
Using a session for paging is usually a bad idea. 1. Multiple windows result in unexpected results. 2. Bookmarks don''t reference the right page and GETS aren''t idempotent. If you want reliable paging that always works you need to include everything in the URL. If you add sorting and filtering/limiting, make sure to mark those links nofollow and/or use javascript, because Google will kill you when it indexes every possible sort and filter combination. -- Posted via http://www.ruby-forum.com/.
Here''s another approach... create a model to hold the page state. The way I did this goes something like this... user has_many :page_views PageView belongs_to :user page_view id :integer page_url :string setting :text The ''setting'' attribute just holds a yaml encoding of the params hash. the ''page_url'' is the uri for the request without the params Then in a before filter, you can load the previous params and overwrite the bits that changed. in an ''after'' filter, you write the modified params back to the table. The nice part here is that it remembers settings for each user, it doesn''t forget the settings when it logs off, and it keeps your session from getting cluttered. On Wednesday, April 26, 2006, at 5:33 PM, Guest wrote:>Using a session for paging is usually a bad idea. > >1. Multiple windows result in unexpected results. > >2. Bookmarks don''t reference the right page and GETS aren''t idempotent. > >If you want reliable paging that always works you need to include >everything in the URL. If you add sorting and filtering/limiting, make >sure to mark those links nofollow and/or use javascript, because Google >will kill you when it indexes every possible sort and filter >combination. > >-- >Posted via http://www.ruby-forum.com/. >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/rails_Kevin -- Posted with http://DevLists.com. Sign up and save your mailbox.
Stephen Friedman
2006-May-01 15:30 UTC
[Rails] Re: Does Rails need more useful URL helpers?
While searching for the solution to another problem, I came across the following URL: http://www.ruby-forum.com/topic/1612. Based on the example code given in this article, I implemented the following method in my ApplicationController class: def default_url_options(options) { :page => params[:page], :sort => params[:sort], :limit => params[:limit] } end And it works like a charm! I just didn''t know the method existed. Next time I will examine the base classes like ActionController::Base more carefully. I wonder if a review of how parameters override other parameters is still in order or whether the above method solves all the needed problems? It effectively provides a single location for the developer to specify all parameters that should remain from one link to another regardless of any other parameter modifications. This can even be specified on a per-controller basis. -- Posted via http://www.ruby-forum.com/.
Stephen Friedman
2006-Jul-18 19:22 UTC
[Rails] Re: Does Rails need more useful URL helpers?
Kevin Olbrich wrote:> Here''s another approach... > > create a model to hold the page state. > > user has_many :page_views > PageView belongs_to :user > > page_view > id :integer > page_url :string > setting :textThe default_url_options method I mentioned last failed terribly. Clashing variable names and an inability to define where they should expire caused params to persist longer than they should have. My company has decided to lean towards params lasting too short than too long and I tend to agree with them. The above version also seems quite excellent, but it won''t work when a view is not tied to a user object, as with the Admin panels in which I was trying to implement sorting. After more months of Rails use and experience, I continue to think param overriding needs a review. Where :controller, :action and :id do not change, link_to''s should retain the current URL''s params except where explicitly and individually overridden. It makes sense for :id to be nulled when :action is set because of the hierarchy of the route. But params in not specified in a route should not be overridden in the same manner. They should all be treated as siblings at the same hierarchical depth. They should only be nulled when a param from the route changes, not when any of their siblings changes. To do otherwise continues to seem unintuitive to me. -- Posted via http://www.ruby-forum.com/.