New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lost page identification on controller render #61
Comments
This is a known issue... It can be partially solved by using the :highlights_on option, i.e.
But this - of course - does also highlight the item on a get request to /events (the index action). I currently can't see a clean way to solve this issue... Any ideas are appreciated.. |
When this issue was logged last night, I briefly wondered if we could solve this using |
Hi superlou, I've created a highlights-on-proc branch with an enhanced I'd suggest trying something like this: events_sub_nav.item "new_event", "New event", new_event_path, :highlights_on => lambda{@event.new_record?} Let me know how it goes and I'll work on pulling the functionality into master and releasing a new version of simple-navigation incorporating the feature and full rspec coverage. :) |
BTW (and you might already know this) but assuming you are using Rails 3, modifying your gem 'simple-navigation', '3.3.3', :path => '/Users/markt/code/simple-navigation' |
Thanks for the quick responses! I had actually included your branch via the following. Is this not recommended? gem 'simple-navigation', '3.3.3',
:git => 'https://github.com/andi/simple-navigation.git',
:branch => 'highlights-on-proc' For new items, it seems to be working with the slight modification to protect against nil objects: :highlights_on => lambda{@event.new_record? if @event.present?} The only concern I might have is what happens if you have a form with accepts_nested_parameters_for. I think that can be handled if you can use both a regex and lambda. The last sticking point is similar, but occurs for edits (CRUD updates) that fail. I can't seem to find an equivalent to new_record? for update (not_updated? would be nice) but will keep looking. |
Would it be possible to do something like the following to catch failed updates? :highlights_on => [/events\/(\d)+\/edit/, lambda{@event.errors.count > 0 if @event.present?}] It looks pretty inelegant to my newbie eye and it would be awesome to bake in functionality for new and edit so they just work. Let me know if there is anything I can do to help. I'm pretty new to ruby and rails and most of my testing has been done via Test::Unit + Shoulda unfortunately. |
Referencing the gem as a branch that way is fine - I just have had lesser success than some with bundler and git references in the past and tend to fall back to base principles (and, of course, this syntax is great for hacking purposes! :-)). Glad to hear it's working for new items. FYI, another pattern to protect against nils could be: lambda { @event && @event.new_record? } Can you provide an example usage where As for edits: perhaps you could make use of the lambda ( @event && @event.changed? } Though this would need to be combined with a regex for the initial before changes. Hmmmm, will think a bit more about this. |
Ah, interleaved comments FTW. :) Yes, I agree, that does look inelegant! I also agree that it would be great to bake functionality in - but this is not a rails specific library and, as such, any bake-ins would need to be carefully constructed so as not to pollute core functionality with railsisms. :) More than happy to take on board and/or collaborate any ideas you have though! |
I like that pattern. Didn't realize boolean logic is happy to terminate early when failing a logic and. Unfortunately, my model using I forgot about the isolation from rails, sorry. If it's a simple as a pattern for :highlights_on => rails_new(@event)
:highlights_on => rails_update(@event) or something of the like. There's probably some fancy meta-programming that could be done so the user doesn't have to remember to add the highlights manually. It doesn't seem worth creating a special rails fork of simple-navigation. Sorry about the following Closed -> Reopened. |
Ok, taking a different approach to this problem, I've been playing about with defining this kind of helper matcher = lambda do |controller,action|
Array(controller).include?(controller_name) && Array(action).include?(action_name)
end And using it like this: events_sub_nav.item "new_event", "New event", new_event_path,
:highlights_on => lambda { matcher.call('events',['new','create']) }
events_sub_nav.item "edit_event", "Edit event", edit_event_path(@event),
:highlights_on => lambda { matcher.call('events',['edit','update']) }, :unless => lambda { @event.nil? } The solution could be generalized further. For eg. in EDIT_ACTIONS = ['edit','update']
CREATE_ACTIONS = ['new','create']
def action_matcher(controller,action)
controllers = Array(controller)
actions = Array(action)
lambda { controllers.include?(controller_name) && actions.include?(action_name) }
end
def edit_action_matcher(controller)
action_matcher(controller,EDIT_ACTIONS)
end
def create_action_matcher(controller)
action_matcher(controller,CREATE_ACTIONS)
end Then, in events_sub_nav.item "new_event", "New event", new_event_path,
:highlights_on => create_action_matcher('events')
events_sub_nav.item "edit_event", "Edit event", edit_event_path(@event),
:highlights_on => edit_action_matcher('events'), :unless => lambda { @event.nil? } How does that grab you? |
It doesn't seem to be working for me (also, small typo pluralizing actions). Just eyeballing it looks like it should work but I'll get into a bit more and report back. |
Ah, yeah, sorry about the (multiple!) typos, corrected in post now. |
One more typo in action_matcher: EDIT_ACTIONS = ['edit','update']
CREATE_ACTIONS = ['new','create']
def action_matcher(controller,action)
controllers = Array(controller)
actions = Array(action)
lambda { controllers.include?(controller_name) && actions.include?(action_name) }
end
def edit_action_matcher(controller)
action_matcher(controller,EDIT_ACTIONS)
end
def create_action_matcher(controller)
action_matcher(controller,CREATE_ACTIONS)
end Working except for an edit action on a nested resource. p.s. I need to refresh the page more often. :) |
Also, doesn't seem to be an issue related to nested resources. It occurs whenever there are 2 siblings at a level of the tree. |
Not quite sure what you mean by 2 siblings at a level of the tree. Can you provide an example or two? Something you can try to use for debugging: def action_matcher(controller,action)
controllers = Array(controller)
actions = Array(action)
lambda do
STDERR.puts "ctrlr: #{controller_name} act: #{action_name}"
controllers.include?(controller_name) && actions.include?(action_name)
end
end |
So, I have two Events (Event A and Event B), when I try to edit (or update) either my breadcrumb looks like:
In the STDERR I see When I remove the highlights_on, I get a more normal result though it only works with edit (not update).
My structure is the following (using a normal list view at the root of the project): Events |
Ah, I see, I guess it's matching on both edit actions within the navigation. If you have an edit entry for each event, you'll need to be selective about matching for the |
Maybe getting a bit messy again, but something like this should work: EDIT_ACTIONS = ['edit','update']
def edit_action_matcher(controller,&additional_condition)
action_matcher(controller,EDIT_ACTIONS,&additional_condition)
end
def action_matcher(controller,action,&additional_condition)
controllers = Array(controller)
actions = Array(action)
lambda do
controllers.include?(controller_name) &&
actions.include?(action_name) &&
( additional_condition.nil? ? true : additional_condition.call )
end
end And then: events_sub_nav.item "edit_event_a", "Edit Event A", edit_event_path(event_a),
:highlights_on => edit_action_matcher('events') { @event == event_a }
events_sub_nav.item "edit_event_b", "Edit Event B", edit_event_path(event_b),
:highlights_on => edit_action_matcher('events') { @event == event_b } I imagine you're already DRYing this stuff up in your |
PS. I've merged the highlights-on-proc branch into master now, and will release a new version of the gem shortly. Please let me know when you've finished with the branch and are using master or the latest gem so I can remove it - ta. :) |
FYI, I'm going to remove the branch tomorrow and close the issue - shout if you think otherwise. :) |
Very sorry not to get back to you! Github stopped sending me the notification emails and I fell behind. I've switched to master so will be ok. Never quite got it working, but haven't gotten to try your most recent comments. Will hopefully get a chance tomorrow evening. If you want to close the issue, be my guest. Again, sorry not to respond until now. |
Ok, will close this, please feel free to reopen if you have more ideas for improvements. |
I have defined a link to a new model inside my navigation heirarchy:
This works great (mostly using simple-navigation for breadcrumbs currently) except when the form is submitted with invalid data. This causes a controller render rather than redirect_to and the browser path is now /events rather than /events/new. From what I've read, this is normal for rails, but seems to be preventing simple-navigation from identifying the page. Is there an option for defining the nav to catch this case?
The text was updated successfully, but these errors were encountered: