Undefined method by link_to helper - html

I need to post through a link tag, however there is a problem with the link helper. Here is my link tag
// doctors.html.erb
<%= link_to "Ekle", [:add_doctor, #patient], method: :post %>
And my routes.rb
// routes.rb
get 'patients/:id/doctors' => 'patients#get_doctors'
post 'patients/:id/doctors' => 'patients#add_doctor'
I get the error
undefined method `add_doctor_patient_path' for #<#:0x007fd39283a4b0>
How should I use link helper to get rid of the problem?

This line in your routes.rb shows that you have a get_doctors route that accepts one argument, :id:
get 'patients/:id/doctors' => 'patients#get_doctors'
That means you should use the corresponding path helper, get_doctors_path, and pass it the Patient object:
<%= link_to "Ekle", get_doctors_path(#patient), method: :post %>
P.S. Your routes are puzzling, since you could accomplish the same thing by using resourceful routes, as recommended by the Rails Guides, instead of defining your own custom get and post routes, and in so doing save yourself a lot of trouble:
resources :patients do
resources :doctors
end
This would create e.g. patient_doctors_path and new_patient_doctor_path path helpers that would automatically route to your DoctorsController#get and DoctorsController#new methods, respectively, and it would enable you to use e.g. form_for [ #patient, :doctor ]. PatientsController is very much the wrong place to put logic for retrieving and modifying Doctors.

Just add an as: option on the routes.
// routes.rb
get 'patients/:id/doctors' => 'patients#get_doctors',as: :patient_get_doctor
post 'patients/:id/doctors' => 'patients#add_doctor', as: :patient_add_doctor
Then in the view:
// doctors.html.erb
<%= link_to "Ekle", patient_add_doctor_path(id: #patient.id), method: :post %>

Related

Rails how to Render a form instead of redirect on submit?

I have a form that the results just show if render instead of redirect.
so the form must not be redirected. someone know if this is possible with rails?
the form is:
Pac: <%= #pac %>
Sedex: <%= #sedex %>
<%= form_tag calculate_ship_path, :method => "get" do %>
<%= text_field_tag :post_code%>
<% end %>
the order controller and action is:
def calculate_ship
frete = Correios::Frete::Calculador.new cep_origem: "#{#order.seller.post_code}",
:peso => "#{#order.product.weight}",
:comprimento => "#{#order.product.weight}",
:largura => "#{#order.product.weight}",
:altura => "#{#order.product.weight}",
cep_destino: params[:post_code]
servicos = frete.calcular :sedex, :pac
#pac = servicos[:pac].valor
#sedex = servicos[:sedex].valor
render '/path/to/rails/app//orders/:id/checkout'
end
and the routes is:
get '/path/to/rails/app//orders/:id/checkout', to: 'orders#checkout', as: :calculate_ship
Rails has a very handy way to handle this: remote forms. The caveat here is that if you're not using Unobtrusive JS (UJS) then this won't work and you'll have to wire it up the hard way.
In form tag notation it would look something like this, presuming you're using Rails 5:
<%= form_tag(calculate_ship_path, remote: true, method: "GET") do %>
<%# form stuff %>
<% end %>
You should be able to do this with most Rails versions, but it might look a little different. What this does, effectively, is submits your form via AJAX. You'll then be able to bind JS event listeners to ajax:success or ajax:error and handle the response you get from calculate_ship.
One thing to note is that when you're doing form submissions, the method is defaults to POST, and probably should be that, a PUT, or a PATCH.
Here's the related docs for rails: http://guides.rubyonrails.org/working_with_javascript_in_rails.html#form-tag

argurments not being passed on edit action, nested objects

I'm trying to write an edit action for a my post object which is nested inside the projects one. By the looks of it I'm doing everything as it should be but for some reason when I comes down to load the form, this error message appears "First argument in form cannot contain nil or be empty"
The params being sent are correct "project_id"=>"308", "id"=>"41", however it seems like the form does not know what to do with them.
form
.....
<div class="row">
<div class="col-md-12" id="postform">
<%= form_for ([#project, #post]), html: { multipart: true } do |f| %>
....
view
....
<% if current_user?(post.user) %>
<%= link_to edit_project_post_path(#project, post ) do %>
....
controller
....
before_action :logged_in_user, only: [:create, :edit]
def edit
#project = Project.find(params[:project_id])
#post = #project.posts.find(params[:id])
end
....
post is a nested object of projects and so it has been config on the route s file.
Any ideas what might be causing this problem?
I thought that maybe I need to specify on the form what are these values used for...
Thanks for the help
---- Edit ----
resources :projects do
resources :comments,:posts
end
resources :posts, only: [:create, :destroy, :edit]
form_for is not supposed to work with multipart: true, try removing that or try with form_tag.
Best regards.

Rails POST params not accessed in controller

I'm trying to write an application that will have to interact with POST but I'm having issues accessing the parameters. This is not meant to be useful right now but I'm just trying to flash the result of the form. According to google dev tools, the POST parameter is set to 1.
Here's my routes.rb file
devise_scope :user do
put 'users/toggle_activation' => 'users/sessions#toggle_activation'
get 'users/sign_out' => 'users/sessions#destroy'
post 'pages/home' => 'users/sessions#activities'
end
This is the controller in question
def activities
params.permit(:tennis)
current_user.save
flash[:notice] = params[:tennis]
redirect_to root_path
end
This is the form code
<%= form_for :user do |f| %>
<%= f.check_box :tennis %>
<%= f.submit %>
<% end %>
Any help is appreciated.
If you're using "form_for", then the check_box name will result as "user[tennis]", not just "tennis". View source in your browser and you should see this.
Do something like the following in your controller method (although I'm not sure how it will be called with "form_for :user" because your "activities" route isn't in your routes.rb in the code above):
user_params = params.require(:user).permit(:tennis)
flash[:notice] = user_params[:tennis]

Controller and action within link_to image_tag don't execute controller code

My link_to looks like this:
<%= link_to image_tag(user_likes_selection.page_picture, :image_id =>
user_likes_selection.id, :controller => :preferences_controller,
:action => :checked_average_with_profile) %>
My controller, preferences_controller, has a method called checked_average_with_profile, which, as far as I can tell, is not being called when I click the image.
The html code that is generated from the link_to is
<img>
<a href="/preferences"><img action="checked_average_with_profile" alt="Soul_surfer_film"
controller="preferences_controller" height="70%" image_id="3254"
src="/assets/soul_surfer_film.jpg" width="70%" /></a>
</img>
Why isn't the controller code executed when the image is clicked?
in cases like these, it's easier to read the code if you use the block form of link_to
<%= link_to { :image_id => user_likes_selection.id, :controller => :preferences, :action => :checked_average_with_profile } do %>
<%= image_tag(user_likes_selection.page_picture %>
<% end %>
in your routes, you can also pass an as option so you can use a named route. assuming your routes looks like
match '/preferences/checked_average_with_profile/:image_id' => 'preferences#checked_average_with_profile', as: :check_average_profile
you can simplify your link using
link_to image_tag(user_likes_selection.page_picture), check_average_profile_path(user_likes_selection.id)
Here is how i do in my code.
<%=link_to(image_tag(user_likes_selection.page_picture), check_average_profile_path(user_likes_selection.id)) %>
Try:
<%= link_to image_tag(user_likes_selection.page_picture), url_for({:controller => 'preferences_controller', :action => 'checked_average_with_profile', :image_id => user_likes_selection.id}) %>
Put your paren after user_likes_selection.id, not at the end. You're mixing image tag properties with your link_to properties.
Try:
<%= link_to image_tag(user_likes_selection.page_picture, :image_id =>
user_likes_selection.id), {:controller => :preferences,
:action => :checked_average_with_profile} %>
Finally solved my problem by adding a collection with my action in resources:
resources :preferences do
collection do
get 'save_new_scores_to_profile'
get 'checked_average_with_profile'
end
end
Then, I modified my view code so that I could pass the image_id variable along to the controller.
<%= link_to image_tag(user_likes_selection.page_picture,
checked_average_with_profile_preferences_path(:image_id =>
user_likes_selection.id) %>
In my controller, I made sure to grab the image_id with params and put a redirect_to at the end:
def checked_average_with_profile
params[:image_id]
redirect_to preferences_url
end
If you have this problem, the key parts are passing the id (whatever that may be) within parenthesis of the controller path you specify and using a COLLECTION instead of a MEMBER in your routing file.

Remove default 'GET' method parameters from URL

I'm using the generic search form, and my url after the search looks like
http://localhost:3000/search?commit=Search&page=2&query=feature&utf8=%E2%9C%93
The search works fine, but I would like to remove the default "utf8=✓" and "commit=Search" parameters from the URL, I'm also using will_paginate and I would like the &page=2 to be after the query parameter leaving it like this:
http://localhost:3000/search?query=feature&page=2
My code:
#posts_controller.rb
def search
query = '%'+params[:query]+'%'
#posts = Post.find(:all, :conditions => ["content LIKE ? or title LIKE ?", query, query]).paginate(:page => params[:page], :per_page => 5)
end
and
#html form
<%= form_tag(search_path, :method => 'get') do %>
<%= text_field_tag "query" %>
<%= submit_tag "Search" %>
<% end %>
and
#routes.rb
match '/search', :to => 'posts#search'
Thanks.
See similar questions:
Rails 3 UTF-8 query string showing up in URL?
removing "utf8=✓" from rails 3 form submissions
Basically, to remove 'commit=Search' add :name => nil to the submit_tag. IE needs the utf8 character. However, the second link has a initializer method to remove that part.
In this video, Ryan Bates talks about the name: nil fix (without ajax): http://railscasts.com/episodes/37-simple-search-form
You cant just remove it from url as far as YOU send it.
To clean up will_paginate try this
<%= will_paginate #whatever, params => params.merge({:commit => nil, :utf8 => nil}) %>
I solved utf problem by using
<form action="<%= root_path %>" method="get" >
...
</form>
instead of form_tag, it solved it.
Ryan Bates did a nice screen cast on exactly what you're trying to do (plus some more).
http://railscasts.com/episodes/240-search-sort-paginate-with-ajax