Route to controller action - ruby-on-rails

I created an form_tag form:
<%= form_tag(set_image_dokumente_path) do %>
<%= text_field_tag :shit,'', data: {autocomplete_source: search2_patients_path}, :class => "shit" %>
<% end %>
I try to route to set_image action of dokumente controller, but i get the error:
undefined local variable or method `set_image_dokumente_path' for #<#<Class:0x711ff60>:0x762d578>
By default my form_tag goes to dokumente controller index action!
My routes:
resources :images
get "dokumente/index"
post "dokumente/index"
match 'patients/list' => 'patients#list'
resources :patients do
collection do
get :search2
end
end
How do i have to change it?

You can add the as: parameter to you route in order to create a named path.
For example:
post "dokumente/index", as: 'set_image_dokumente'
or similar, I'm not sure what you are trying to achieve, but I hope you get the idea :)
More info:
http://guides.rubyonrails.org/routing.html#generating-paths-and-urls-from-code

Related

Rails has_many through association delete path

I have a place model and a user model and a user_place model, user_place belongs to user and place both. Traditional has_many through association.
I have a page where you can view the users associated with a place. My routes look like:
resources :places do
resources :user_places
end
which generates these routes:
place_user_places GET /places/:place_id/user_places(.:format) user_places#index
POST /places/:place_id/user_places(.:format) user_places#create
new_place_user_place GET /places/:place_id/user_places/new(.:format) user_places#new
edit_place_user_place GET /places/:place_id/user_places/:id/edit(.:format) user_places#edit
place_user_place GET /places/:place_id/user_places/:id(.:format) user_places#show
PATCH /places/:place_id/user_places/:id(.:format) user_places#update
PUT /places/:place_id/user_places/:id(.:format) user_places#update
DELETE /places/:place_id/user_places/:id(.:format)
I don't love this but I'm ok with it for now.
But whenever I try to delete a user_place I have all sorts of issues.
<%= link_to "delete", place_user_place_url(place_id: #user_place.place_id, id: #user_place.id), method: 'delete' %>
No route matches {:action=>"show", :controller=>"user_places", :id=>nil, :place_id=>2}, possible unmatched constraints: [:id]
I had this working previously with slightly different routes and an actual form:
resources :places do
resources :user_places, as: 'user', only: %i[index create new]
delete 'remove_user', to: 'user_places#remove_user'
end
<% if user != current_user %>
<%= form_with model: #user_place, url: place_remove_user_path(#place.id), method: 'delete' do |form| %>
<%= form.hidden_field :user_id, value: user.id %>
<%= form.hidden_field :place_id, value: #place.id %>
<%= form.submit "delete" %>
<% end %>
<% end %>
But this feels hacky, I don't think I should need a specific form, and this was leading the form to be submitted with javascript which I don't want.
What might be a solution is to use shallow nesting in the routes (shallow: true).
resources :places do
resources :user_places, shallow: true
end
Make sure to run rails routes again. The delete method of a user_place will no longer be nested.
You can then simply delete the user_place passing a single variable (an instance of a user place, #user_place). There is no need to set the id (place_id or id) as Rails is smart enough to handle that. Just passing an instance variable is enough for the delete method to find the corresponding record.
<%= link_to "delete", user_place_url(#user_place), method: 'delete' %>

Rails: Routing and form for custom controller method

I'm getting this error attempting to create a page that shows room details. Pressing on edit will triggger a popup window with prefilled values of the room clicked. And clicking save on the window will update data for that entry.
I'm not so sure how to predefine the id, I'm currently using jQuery to populate the form with current data of selected records.
No route matches {:action=>"save_details", :controller=>"rooms"}, missing required keys: [:id]
rooms/index.html.erb
<%= form_for(#room, url: save_details_room_path) do |f| %>
<% f.text_field :id, id:'edit-room-id', class:'d-none' %>
<% f.text_field :name, id:'edit-room-name' %>
<% f.text_area :desc, id:'edit-room-desc', style:'width: 90%; height: 8em; resize: none; float: bottom' %>
<%= f.submit 'Save', :class=>'btn btn-primary' %>
<% end %>
rooms_controller.rb
def save_details
logger.info ('Hello world')
#room= Room.find(params[:id])
#room.name = params[:name]
#room.description = params[:desc]
#room.save
redirect_to rooms_url
end
def show
#room = Room.find(prams[:id])
end
def index
#room = Room.all
end
routes.rb
resources :rooms do
get :save_details, on: :member
end
main.js
const name = $(this).data('name');
const desc = $(this).data('description');
const id = $(this).data('id');
$('#edit-room-id').val(id);
$('#edit-room-name').val(name);
$('#edit-room-desc').val(desc);
1ST EDIT:
Now I'm doing this another way which is just to simply pass the form as a url through, eg. /rooms/save_details?id=1,name=123,desc=1234. However the form just simply routes it into the default show/index methods in my controller. Anyway to route it directly to save_details method? Doing the below simply returns the error that says save_details does not exist as an id. Also editted my routes
new routes.rb
get '/rooms/save_details/:id/:name/:desc' => 'rooms#save_details', :as => 'save_details'
index.html.erb
<form action="rooms/save_details" method="get">
....
</form>
Looks like you're trying to save a form, this probably shouldn't be a get
resources :rooms do
post :save_details, on: :member
end
You're missing the :id parameter on your route helper. You need to do:
<%= form_for(#room, url: save_details_room_path(id: #room.id)) do |f| %>
And as Asthmatic suggested, that will have to be a :post route if a form is being submitted to it.
It appears you're using jQuery to fill in the room id, so you may have to skip the Rails form helper in favor of a plain HTML form. In that case you'll have to build and add the action attribute after you have the room id.
Finally solved it by using a normal HTML form and adding the following in routes.rb
get '/rooms/save_details/:id/:name/:desc' => 'rooms#save_details', :as => 'save_details'
resources :rooms do
get 'save_details', on: :collection
end

Rails: Trying to add search function - keep getting "no route matches"

I'm trying to implement a simple search function for my Rails app by following this guide. I am trying to allow users to search for animal by name.
Here's my current code:
controllers/animals_controller.rb
class AnimalsController < ApplicationController
def search
#animal = Animal.search(params[:search])
end
end
Here's my views/animals/index.html.erb
<%= form_tag :controller => 'animals', :action => 'search', :method => 'get' do %>
<%= text_field_tag :search, params[:search], :id => 'search_field' %>
<%= submit_tag "Search", :name => nil %>
<% end %>
And here is the error I keep getting:
No route matches {:action=>"search", :controller=>"animals",
:method=>"get"}
I don't understand why this isn't working. I have the search function defined in the animal_controller.rb. Can anyone point out why the search function may not be working?
Based on the guide you are following, creating a GET /search route was never mentioned. You can define the route in config/route.rb with this
resources :animals do
get :search
end
or
get search: "animals#search"

Rails Form_tag syntax error

I get an error when I run this code. I want to make a button that redirects to an action from pages_controller.
Submultimi.html.erb
<%= form_tag({:controller => '/pages_controller', :action => 'calculeaza'}, :method => "post") do %>
<%= text_field_tag :field1 %>
<%= submit_tag "Button" %>
<% end %>
pages_controller.rb
def Submultimi
end
def Combinari
end
def Permutari
end
def calculeaza
puts "YAY"
redirect_to '/combinari'
end
Error message: No route matches {:action=>"calculeaza", :controller=>"pages_controller"}
routes.rb
Rails.application.routes.draw do
get '/submultimi' => 'pages#Submultimi'
get '/combinari' => 'pages#Combinari'
get '/permutari' => 'pages#Permutari'
end
If you get an error you must include the error message in the question. Anyway the controller name is obviously wrong so this must be the problem. The controller should not include the "/" nor the "_controller".
<%= form_tag( { :controller => 'pages', :action => 'calculeaza' }, :method => "post") do %>
<%= text_field_tag :field1 %>
<%= submit_tag "Button" %>
<% end %>
Your routes are also wrong:
there's no calculeaza method in routes
methods should be lowercase in routes and controller
Thanks to Phlip for the correction about the controller name :)
As Pablo said, remove the / from your controller name.
Your error message says there is no route defined. That means you haven't correctly told rails what to do with your form's post request; it's trying a route that doesn't exist.
You've got a few things going wrong. Your action names are capitalized in routes.rb, but your method names (at least the one you've linked) is not. They're case sensitive, convention is all lowercase. Also, you don't have a route defined for calculeaza. You need one, in routes.rb add (something like, I haven't tested any of this):
post '/calculeaza/' to 'pages#calculeaza'
If you want to see your currently defined routes, run rails routes in a terminal, and to use it in code append _path to the prefix verb. You end up with something like:
form_tag calculeaza_path do
You may want to read the rails routing guide, especially the parts about resourceful routes.

undefined method `posts_path' for #<#<Class:0x007fe3547d97d8>:0x007fe3546d58f0>

I'm new to rails and I'm getting this error:
undefined method `posts_path' for #<#<Class:0x007fe3547d97d8>:0x007fe3546d58f0>
I've posted my files below, please keep in mind I'm new to rails so simple explanations would be really appreciated!
Route.rb:
Rails.application.routes.draw do
get '/post' => 'post#index'
get '/post/new' => 'post#new'
post 'post' => 'post#create'
end
post_controller.rb:
class PostController < ApplicationController
def index
#post = Post.all
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to '/post'
else
render 'new'
end
end
private
def post_params
params.require(:post).permit(:content).permit(:title)
end
end
new.html.erb:
<%= form_for(#post) do |f| %>
<div class="field">
<%= f.label :post %><br>
<%= f.text_area :title %>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit "Create" %>
</div>
<% end %>
I'm guessing form_for(#post) expects there to be a method called posts_path and one doesn't exist because it hasn't been defined in your routes file. Try replacing:
Rails.application.routes.draw do
get '/post' => 'post#index'
get '/post/new' => 'post#new'
post 'post' => 'post#create'
end
with
Rails.application.routes.draw do
resources :posts, only: [:new, :create, :index]
end
Edit: more info:
Read the full page on form helpers at http://guides.rubyonrails.org/form_helpers.html, and inparticular, read the section on "2.2 Binding a Form to an Object" and the part that says:
When dealing with RESTful resources, calls to form_for can get
significantly easier if you rely on record identification. In short,
you can just pass the model instance and have Rails figure out model
name and the rest:
## Creating a new article
# long-style:
form_for(#article, url: articles_path)
# same thing, short-style (record identification gets used):
form_for(#article)
## Editing an existing article
# long-style:
form_for(#article, url: article_path(#article), html: {method: "patch"})
# short-style:
form_for(#article)
Notice how the short-style form_for invocation is conveniently the
same, regardless of the record being new or existing. Record
identification is smart enough to figure out if the record is new by
asking record.new_record?. It also selects the correct path to submit
to and the name based on the class of the object.
So, knowingly or not, when you say form_for(#post), you're asking rails to guess the route that your form should be submitted to, based on the name of your #post variable. The routes that you had defined didn't match what rails expected them to be.
For more on routing in rails read the entire page at http://guides.rubyonrails.org/routing.html, and inparticular pay attention to the section "2 Resource Routing: the Rails Default". Your form_for(#post) will assume that you're using "resource routing", which is what I switched to.
As for why your getting a new error? There's somewhere else in your app where you were expecting to use your previous custom defined routes, and now you're using rails "resource routes" so your path names will be different. No route matches [GET] "/post/new" because now the route instead matches No route matches [GET] "/posts/new" (note the plural posts).
Here the form is try to find a route to a post_method through a path "posts_path"
So you need to define in your routes.rb file.
Rails.application.routes.draw do
get '/post' => 'post#index'
get '/post/new' => 'post#new'
post '/posts' => 'post#create'
end
The problem arises from the views. Rails cannot recognize the path that will run when the form is submitted.
You can manually change your form_for tag to point to the appropriate url.
<%= form_for #post, :url => "enter_your_path_here" do |f| %>
This solved my similar problem
you need to rename the post controller and the corresponding files to plural. that's posts not post. and then the route too needs to be resources :posts.
don't forget to change the class name of your post controller to be plural.

Resources