Rails link_to nested resources - ruby-on-rails

I created a nested resources but my link_to shows undefined method 'model_name' for Parking::ActiveRecord_Relation:Class in the browser. I did it wrongly, obviously. How can I correct it?
index.rb
<%= link_to 'Create new parking', new_parking_path %></br>
<%= link_to 'Rent place', [#parking, #place_rent]%>
routes.rb
resources :parkings do
resources :place_rents, :only => [:new, :create]
end

Either #parking or #place_rent is a relation (collection) and not a particular model which you would need to build a route. Depending on what is behind these variables you might need a #first or whole different query.

Related

No route matches [GET]. Trying to [PUT]. Rake routes shows this path with put and patch

routes.rb
namespace :scheduling do
resources :scheduling_details, only: [:create, :destroy, :update, :index]
do
rake routes
scheduling_scheduling_detail
PATCH /scheduling/scheduling_details/:id(.:format)
scheduling/scheduling_details#update
PUT /scheduling/scheduling_details/:id(.:format)
scheduling/scheduling_details#update
view
<%= link_to "Yes", scheduling_scheduling_detail_path(#scheduling_detail) %>
Error. No route matches [GET] "/scheduling/scheduling_details/6256"
Notice the plural there. I'm not sure why it's trying to access the plural url when I didn't use the plural path shortcut.
So I try to use the manual url instead of the path shortcut
<%= link_to "Yes", "/scheduling/scheduling_detail/#{#scheduling_detail}" %>
Error: No route matches [GET] "/scheduling/scheduling_detail"
Maybe try with the id?
<%= link_to "Yes", "/scheduling/scheduling_detail/#{#scheduling_detail.id}" %>
Error: No route matches [GET] "/scheduling/scheduling_detail/6256"
Try adding :show to your array, like so:
namespace :scheduling do
resources :scheduling_details, only: [:create, :destroy, :update, :index, :show]
do
And make sure you have a show method in your controller and a view.
As per your routes printout:
Your paths are plural. The issue is that you don’t have a GET method, which corresponds to the show view.
You’ll want to change your link_to method to PUT or PATCH.
Something like this in your view should work:
<%= link_to "Yes", scheduling_scheduling_detail_path(#scheduling_detail), method: :put %>
https://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to
You are specifying the wrong path using scheduling_scheduling_detail you are specifying the #GET Request you need to use the update_ prefix to specify PUT/PATCH. The following would do the trick.
<%= link_to "Yes", update_scheduling_scheduling_detail_path(#scheduling_detail) %>

How to add params id in rails link_to

I have a Job model that contains a Company_id as a foreign key. On the company show page, I want to use a link_to tag that links to the Job new page so I can create a new job with the company_id using simple_form.
<%= link_to "Create Job", new_company_job_path %>
I get this error "No route matches {:action=>"new", :controller=>"jobs", :id=>"13"}, missing required keys: [:company_id]"
This is my nested route
resources :companies do
resources :jobs, only: [:new, :create, :update, :destroy]
end
From rails routes, this is the route to the job new page
new_company_job GET /companies/:company_id/jobs/new(.:format) jobs#new
This is the simple-form in the job_new page
<%= simple_form_for (#job) do |f| %> etc
I would like know how I can include the company_id in to the link_to tag in order to use simple_form in the job new_page to create a new job.
Rails routes can take arguments; if you ever want to explicitly pass a parameter to a route you can do so just like you would pass an argument to any other method:
<%= link_to "Create Job", new_company_job_path(company_id: #company.id) %>
*note: this assumes you have defined #company somewhere on this view.
In the case of general resource routes, Rails is smart enough to insert these params in the right place. It's worth noting though that if a param is not defined on the route in routes.rb Rails will tack on these passed parameters to the end of the route as query strings.
For example, if you have a route like
get 'landing_pages/page' => '#landing_pages#page'
and you called:
<%= link_to "Go to your landing page", landing_pages_page_path(brand: 'Apple') %>
The route will become /landing_page/page?brand=Apple
For further reference: http://guides.rubyonrails.org/routing.html

Unable to log out of clearance gem

I have recently move my project away from the somewhat bloat devise to clearance, though I am experiencing troubles when attempting to log out
I am currently get the error of the route not existing
No route matches [GET] "/sign_out"
routes
resources :passwords, controller: "clearance/passwords", only: [:create, :new]
resource :session, controller: "clearance/sessions", only: [:create]
resources :users, controller: "clearance/users", only: [:create] do
resource :password,
controller: "clearance/passwords",
only: [:create, :edit, :update]
end
get "/sign_in" => "clearance/sessions#new", as: "sign_in"
delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
get "/sign_up" => "clearance/users#new", as: "sign_up"
constraints Clearance::Constraints::SignedIn.new do
root :to => 'shopping/merchants#index', as: :signed_in_root
end
constraints Clearance::Constraints::SignedOut.new do
root to: 'clearance/sessions#new'
end
view
= link_to sign_out_path, method: :delete, class: 'mdl-navigation__link' do
i.material-icons> exit_to_app
= t('.log_out')
The message is telling you there is not get route for sign_out, which is correct. You must do a delete. This means, despite your efforts with method: :delete, the link is executing a get request. There's something about your link_to that is not correct. It likely has to do with passing method while using the block form of link_to.
Try:
<%= button_to "Sign Out", sign_out_path, method: :delete %>
If that works, try:
<%= link_to "Sign Out", sign_out_path, method: :delete %>
If both of those work, then the issue is indeed with the way you're using the block form of the link_to helper and has nothing to do with Clearance.
I thought I'd follow up on this with a little more insights for anyone who found themselves here still wondering exactly what is behind this.
As suggested by Derek, to get this sorted, you'll need to use the button_to instead of link_to, as follows:
<%= button_to "Sign Out", sign_out_path, method: :delete %>
Why can't I just use link_to?
So more insights into this are delivered by this previous SO. Essentially, you can't make a link operate as a DELETE method, only GET.
If you have a look at how link_to is actually rendered in HTML on the page (after Ruby works its magic), you'll see the following:
<a rel="nofollow" data-method="delete" href="/sign_out">Sign out</a>
And it's clear that data-method="delete" is still not going to cut it, and still runs the request as GET.
But I don't want a button, I want a link?
Your best bet is to look at some CSS on the element to get it back to looking like a link, otherwise, you'll need to go the Javascript route.
Non-RESTFUL Clearance Centric Dirty Hack - Not Advised!
Using link_to, change your routes.rb where the clearance route currently says:
delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
to:
get "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
It'll route the GET request to the destroy action on the Clerance controller. I dare say this is not advised and Derek could support why this was not supported in the first place (Devise gem does support this dirty hack)

In a Rails app, how can I use a button to run a non-restful controller method? Getting no routes error

In my application I have a link_to helper method:
<%= link_to "Downgrade", :controller => :subscriptions, :action => :downgrade, class: "btn btn-primary", remote: true %>
In my controller I have this code:
class SubscriptionsController < ApplicationController
respond_to :js
def downgrade
# some code
end
end
I am getting this error:
No route matches {:action=>"downgrade", :class=>"btn btn-primary", :controller=>"devise/subscriptions"}
Here is my routes.rb code:
Rails.application.routes.draw do
resources :wikis
devise_for :users
resources :users, only: [:update]
root to: 'welcome#index'
resources :charges, only: [:new, :create]
end
I know Rails is expecting a route for this but I don't know what route I would use since the method isn't a restful verb. Maybe there is another way without using the link_to which allows me to directly call a controller method from a view? Maybe I need to restructure where things are as well. Any help is appreciated.
Let me know if there is more code you would need to fully assess this situation.
Basic setup
first you need to setup your route in routes.rb
get 'downgrade' => 'subscriptions#downgrade', :as => :downgrade_subscription
This will redirect /downgrade to your subscriptions controller & downgrade action. The as option saves this route into a variable you can call from all your views.
<%= link_to "Downgrade", downgrade_subscriptions_path, class: "btn btn-primary", remote: true %>
Further configuration
You can also nest this route inside your subscription resources like so:
resources :subscriptions do
get 'downgrade' => 'subscriptions#downgrade', :as => :downgrade_subscription
end
This will create the path /subscriptions/downgrade instead of /downgrade.
The Rails Docs on routing does a great job explaining this in more detail. Definitely check it out!
or you can try this on your routes.rb
match '/downgrade_subscription', :to => 'subscriptioni#downgrade', :via => :get

Redundant Rails Routes

Why is it that my <%= form_for charges_path %> returns an undefined local variable when visiting /product/:product with these routes :
get 'product/:product' => 'charges#new'
post 'product/:product' => 'charges#create'
but works when I add these?
resources :charges, :only => [:new, :create]
I'd like to clean this up
When you use the get and post methods you don't get the path helpers created, ie. there is no charges_path method unless you provide a string with the :as option.
So without charges_path method, ruby thinks it's the name of a variable and so you get the error you're getting.

Resources