Rails link_to_remote degradation and url_for - ruby-on-rails

I am trying to create a link to destroy and entry in the DB using AJAX but I also want it to function without JavaScript enabled
However the following code
<%=link_to_remote "Delete", :update => "section_phone", :url => {:controller => "phone_numbers", :action => "destroy", :id => phone_number_display.id }, :href => url_for(:controller => "phone_numbers", :action => "destroy", :id => phone_number_display.id)%>
produces the output
Delete
For some reason the url_for does not work properly and the href tag is set to #.
I do not know why this does not work since I am not notified of any errors in the log
Does anyone know why this could be?
Thank you

You're missing curly braces around the options{} hash, which :update and :url belong to, to separate them from the html_options{} hash that :href belongs to.
Try this:
<%=link_to_remote "Delete", {:update => "section_phone", :url => {:controller => "phone_numbers", :action => "destroy", :id => phone_number_display.id }}, :href => url_for(:controller => "phone_numbers", :action => "destroy", :id => phone_number_display.id)%>
That'll get the URL to show up as the href attribute of your link, but a GET request to your destroy action shouldn't delete it. You'll need something else (like what vrish88 suggests) so that you can make a GET request to the destroy action to get a form, then POST that form to actually delete the phone number.

I believe your looking for something like this: RailsCasts - Destroy Without JavaScript

Related

How to pass a parameter from view to controller

I have an app in ruby on rails with a view which has some parameters displaying on screen.
<%= link_to l(:label_statistics),
{:action => 'stats', :id => #project, :repository_id => #repository.identifier_param},
:class => 'icon icon-stats' if #repository.supports_all_revisions? %>
I'd like to catch the variable #repository.name and use it in the function I have in my controller.
How do I to do it?
In your stats action, assuming you have a Repository model and the record containing name exists in your database.
#repository = Repository.find(params[:repository_id])
#repository.name
If not, you could pass it along with everything else,
<%= link_to l(:label_statistics),
{:action => 'stats',
:id => #project,
:repository_id => #repository.identifier_param,
:repository_name => #repository.name},
:class => 'icon icon-stats' if #repository.supports_all_revisions? %>
Then in the controller, access it via params[:repository_name]
Just pass it through the parameters. Doc for li_to.
link_to can also produce links with anchors or query strings:
link_to "Comment wall", profile_path(#profile, :anchor => "wall") # => Comment wall
link_to "Ruby on Rails search", :controller => "searches", :query => "ruby on rails" # => Ruby on Rails search
link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux") # => Nonsense search

how can I enable my form to use ajax in ruby on rails using haml?

I am trying to create a form to send data via ajax and order to update a user (I used scaffolds, so the methods for update already exist).
I created my form and I did something like this
%form{ :action => "/users/customsave", :method => "post", :controller => "/users", :remote=>"true"}
according what I read with saying :remote => true would do it with ajax, the problem is that doesnt work and the worst part is that kills my session for some weird reason after I submit the post.
Any idea how to do this? submit with ajax?
Thanks
You can use
%form{ :action => "/users/customsave", :method => "post", :controller => "/users", data: {remote: true}}
You can use
= form_for 'model', url: "/users/customsave", method: :post, data: { remote: true } do |f|
= f.text_field 'field_name'
/ generates <input type="text" name="model[field_name]"
id="model_field_name"
value="value of the field in case you don't specify string,
instead an actual model">
You should declare your form like so:
= form_tag({:controller => "users", :action => "customsave"}, :remote => true)
You should use the form helpers, as #MrYoshiji told in his comment, for example, form_tag
However, if you still wants to use HAML, you need to use data-remote:
%form{ :action => "/users/customsave", :method => "post", :controller => "/users", 'data-remote'=>"true"}
But beware, because this is not the expected interface and might change in the future, causing an expansive upgrade from your side.
First, you'll need to use form_for or form_tag, %form creates an html form like so:
= form_tag({:controller => "users", :action => "customsave"}, :remote => true)
Second, make sure you actually create a customsave.js.erb js view to handle the response of the ajax request.

How do properly delete this?

Something is seriously not adding up here.. My page just refreshes, nothing happens, it never touches any of my debuggers hanging out on all my methods except for index.
my html:
<%- for image in #images %>
<%= image.attachment_file_name %>
<%-# link_to_delete image, :url => destroy_image_admin_wysiwyg_path(image.id) %>
<%= link_to 'delete', { :url => destroy_image_image_path(image.id) },
#:confirm => 'Are you sure?',
:post => true
%>
<br />
<% end %>
my controller
def destroy_image
debugger
#img = Image.find(params[:id])
#img.destroy
respond_to do |format|
format.html { redirect_to admin_image_rotator_path }
end
end
My routes:
map.resources :images, :member => { :destroy_image => :post }
My disgusting hack that works that I will replace as soon as I find something better
I moved the action over to a simpler controller I built myself.
Changed my routes to :
admin.resources :wysiwygs, :member => { :destroy_image => :post }
Changed my html :
<%= link_to 'delete', :controller => "wysiwygs", :action => "destroy_image" %>
But when I clicked on the link..it brought up.. the show action ?? fffffffffuuuuuuu
I retaliated by just moving my action to the show action, and passing a hidden field in my html..
<%= link_to 'delete', :controller => "wysiwygs", :action => "destroy_image", :hidden_field => {:value => image.id} %>
def show
# this was previously in destroy_image
#img = Image.find(params[:hidden_field][:value])
#img.destroy
respond_to do |format|
format.html { redirect_to admin_image_rotator_path }
end
end
It seems you're going down the wrong path here. If a before_filter is blocking your action, figure out why. Use skip_before_filter :filter_name if the filter is not needed.
Don't use show actions or HTTP GET for deletes. Even if it works, it will confuse things down the road. Use a DELETE verb:
map.resources :images, :member => { :destroy_image => :delete }
pass it in the link helper:
<%= link_to "delete", destroy_image_image_path(image), :method => :delete %>
And use ImagesController#destroy_image to perform the action. Better yet, consider using the standard RESTful ImagesController#destroy which map.resources gives you for free.
Not sure what was wrong in the first place, but in your second, working solution, i think you should write your link_to as follows:
link_to 'delete', :controller => "wysiwygs", :action => "destroy_image", :id => image.id
That at least would send you to the correct action.
Depending on your routes, you will have to make this a method => :post or not.
Check your rake routes output, it will show you what are the possible routes, and also what names they got, which in turn you can use as a method (add _path or _url at the end). Then it should be even easier to write something like:
link_to 'delete', wysiwygs_destroy_image_path(image)
Good luck!
You're doing a POST but your resource says that :destroy_image is only available via GET. Try changing your route to:
map.resources :images, :member => { :destroy_image => :post }
Also, take a look at your link_to. The second parameter takes a URL, not a hash that has a :url key. As mentioned elsewhere, depending on your Rails version you may need :method => :post instead of :post => true. In Rails 2.3.8, you would want this line instead:
<%= link_to 'delete', destroy_image_image_path(image), :method => :post %>

Ruby on Rails: link_to_remote and rel

I want a link to remote to have a rel tag, because I want to use facebox with it.
I had it working with a regular link to... but I needed the link to remote to handle the event that a user doesn't have javascript enabled.
this, currently does't work (except for the non-javascript part )
<%= link_to_remote "Ask a Question",
{:url =>
{:action => :ask_question,
:id => #container.id.to_s,
:javascript_disabled => false
}, :rel => 'facebox'},
:href => url_for(
:controller => :view,
:action => :ask_question,
:id => #container.id.to_s,
:javascript_disabled => true) %>
In link_to_remote you pass in HTML options (like rel) in the third argument. In your code you're passing it in the second (i.e. the first hash). Try this instead:
<%= link_to_remote("Ask a Question",
{ :url => { :action => :ask_question,
:id => #container.id.to_s,
:javascript_disabled => false
}
},
{ :href => url_for( :controller => :view,
:action => :ask_question,
:id => #container.id.to_s,
:javascript_disabled => true ),
:rel => 'facebox'
}
)
%>
(As you know, some of the parentheses and curly braces are optional, but here I've included all of them for clarity, and probably would keep them in since you're passing a lot of complex arguments here.)

Field accessing incorrect controller action on onChange

I have a website and before i included the design and some changes(layout, scripts, etc), it was working fine. Then, I don't know what happened but the onChange method from my select field is accessing "show" action instead of the one that's written in the line.
I have the following at my New view:
<%= collection_select('category', 'id', #categories, 'id', 'name', {:prompt => "Choose a category"}, {:onchange => "#{remote_function(:url => {:controller => 'announcements', :action => "update_subcategories"}, :with => "'parent_id='+value")}",:class => 'newAd_box2_inputField'}) %>
The idea is that it updates a second select field with records related to the selected one.
The second select looks like this:
<%= render :partial => 'category_select', :object => #subcategories %>
Again, it was working great before I introduced some changes, but now it just won't go to "update_subcategories" action, it just goes to "show".
In my routes.rb I've got the following:
map.show "/announcements/:permalink", :controller => 'announcements', :action => 'show'
map.new "/announcements/new", :controller => 'announcements', :action => 'new'
Does anybody know what's going on?
This is your problem.:
map.show "/announcements/:permalink", :controller => 'announcements',
:action => 'show'
Rails will use the first route to appear in routes.rb that matches the parameters given. This behaviour kicks in both when generating urls for output with url_for (which is what the :url option for remote_function does in the background) and mapping urls received by the server to actions.
The above route will generate the route /announcments/update_subcategories so the link will appear right when you view source the source in your browser. But when you go to that link, Rails will match it to the show action of the announcements controller.
The fix depends on which method you're using to define routes for the announcements controller. Regardless of which fix you use, it must come before the bad route. (map.show "/announcements/:permalink", :controller => 'announcements', :action => 'show')
If you're using restful routes the fix is to add a :collection option to the definition.
map.resources :announcements, :collection => {:update_subcategories => :get}
If you're not using restful routes the fix is to add a route.
map.connect "/announcements/update_subcategories",
:controller => "announcements", :action => "update_subcategories"

Resources