Rails 4 Routing - undefined local variable - ruby-on-rails

I have a payments table. In the index view I list all payments in a table and in the show view I'd like to show a form of all payments where a user can select which ones to further process.
Above the table in the index action view I have:
<%= link to "Customise", show_payment_path %>
Then in the controller:
def show
#payments = Payment.all
end
In my routes file:
resources :payments
The error I am getting is:
undefined local variable or method `show_payment_path'
I have tried
<%= link_to 'Customise Sepa Mandate', show_payments_path %>
as well but that gives the same error. As does using url instead of path.

The path for resourceful-routed show actions is just payment_path (singular resource) or payment_path(id). Your “customize” link would lead me to believe you actually want edit_payment_path(id), though.
See Rails Guides — Generating Paths and URLs From Code for more info.

Run rake routes command to see available routes and correct syntax.
Pass show_payment_path(:id) to get the particular payment show page.

for that make your own routes and create their own path variable such as
resources :payments, except: [:show] do
get '/show' => "payments#show", on: collection, as: :show
end

Related

Rails Nested Resource Scoped to Controller

In my app, websites have many pages. I'm trying to setup my URLs to look like
example.com/websites/1/pagename
I want it so page names don't need to be globally unique. They just need to be unique within the website they belong to.
This is what my routes look like so far
resources :websites do
resources :pages, :path => ''
end
UPDATE
I got it working by changing this line in the pages controller.
def show
#page = Page.find_by(website_id: params[:website_id], id: params[:id])
end
However, then I updated that line to use Friendly ID...
def show
#page = Page.friendly.find_by(website_id: params[:website_id], id: params[:id])
end
Now I get an error undefined method name for nil:NilClass because I have <% provide(:title, #page.name) %>
No, You don't need.
The rails g controller websites/pages to use with namespace.
Your URL: websites/1 the id = 1 is unique. and the pagename also unique for each website
=> websites/1/pagename is unique
It's fine for:
websites/1/page_about_author
and
websites/2/page_about_author

Ruby On Rails adding new page after scaffolding

I made a scaffold named b_page and I created a migration for bio I added a biopage.html.erb
In controller:
def biopage
#b_pages = BPage.all
end
in routes.rb
resources :b_pages do
collection do
get 'biopage'
end
end
in bio.html.erb:
<div class="jumbotron">
<h1>Bio of :</h1>
<h2><b><%= #b_page.Bpage_name %></b></h2>
<h3><%= #b_page.user.email %></h3>
</div>
<%= #b_page.bio %>
but i still get the error:
ActiveRecord::RecordNotFound in BPagesController#show
Couldn't find BPage with 'id'=biopage
highlighting:
#b_page = BPage.find(params[:id])
First of all, this seems a bit odd to me:
resources :b_pages do
collection do
get 'biopage'
end
end
as it will result in a route like: /b_pages/biopage. You might want to just do something like:
resources :b_pages, except: :show
get '/biopage/:id', to: 'b_pages#show'
This way, your biopage route will go to the show controller method and you will still have the other b_pages routes to work with.
You are seeing the ActiveRecord::RecordNotFound error message because you have no BPage object to show, so the show method is complaining. Notice how the route I wrote above uses :id - this is because the show action normally takes an id of some record to display on the front end. If you want to use biopage and link it to the show method, you should be returning an object to actually show. Otherwise you should probably create a completely different controller method for biopage that does not interfere with the b_pages resources. Something like this in the routes:
resources :b_pages
get '/biopage/:id', to: 'b_pages#your_method'
and in the controller you'd have
class BPages < ApplicationController
# index, show, destroy, etc. here
def your_method
# Get whatever object you want returned here
end
end

Rails form builder with admin namespace

The code below works well to create new transactions on the Invoice show view. It however doesn't work when in admin namespace. i.e /admin/invoices/1/ but works on /invoices/1/
show.html.erb
<%= form_for([#invoice, #invoice.transactions.build]) do |form| %>
....
transactions form input
routes.rb
resources :invoices do
resources :transactions
end
When calling form_for in a namespace route like /admin/invoices/1/, Rails will automatically append admin to your route. In other words, form_for([#invoice, #invoice.transactions.build]) would POST to a route like /admin/invoice/:id/transactions/ rather than /invoice/:id/transactions/.
To fix, explicitly set the URL of the form and use a route helper method to infer the correct route:
form_for(#invoice, url: invoice_transaction_url(#invoice.id))
Note that you may need to replace invoice_transaction_url with the correct route. Use rake routes to find the helper method that corresponds to the desired controller POST action.

Rails 4 - Hash in route gets rendered wrongly

I have this line of code in routes.rb
get 'products#:id' => 'products#index', as: :products_hash
It works, but the problem is that the hash symbol (#) gets rendered as %23.
http://localhost:3000/products%2368
This is what it should be:
http://localhost:3000/products#68
How can I achieve this? Thanks!
Rails
I feel you're missing the point of Rails' routing system, which is that you are meant to construct it around objects (hence why you call resources :controller etc).
Although I don't understand why you're defining the route you are, I'll give you some ideas. There is a "wildcard" setting for your routes in Rails, which allows you to define & pass parameters to your application out of the scope of the typical "CRUD" based applications:
#config/routes.rb
get 'products#*id' => 'products#index', as: :products_hash
This will give you the ability to send requests to the following route:
<%= link_to "Product", products_hash_path("68") %>
You'd then be able to call the param in the controller:
#app/controllers/products_controller.rb
class ProductsController < ApplicationController
def index
id = params[:id]
end
end

How do I create a rails controller action?

My rails app has a single CustomerSelectionController, with two actions:
index: which shows a form where the user can enter customer information and
select: which just displays a static page.
class CustomerSelectionController < ApplicationController
def index
end
def select
end
end
I've created an entry in my routes.rb file:
resources :customer_selection
and the form in the index view looks like:
<h1>Customer Selection</h1>
<%= form_tag("customer_selection/select", :method => "get") do %>
<%= submit_tag("Select") %>
<% end %>
however when I click on the Select button in the browser, all I get is:
Unknown action
The action 'show' could not be found for CustomerSelectionController
I'm not sure why it is trying to perform an action called show? I haven't defined or referenced one anywhere.
I'm not sure why it is trying to perform an action called show? I haven't defined or referenced one anywhere.
Yes you have. That's what resources does. It defines the seven default RESTful routes: index, show, new, create, edit, update and destroy. When you route to /customer_selection/select, the route that matches is "/customer_action/:id", or the "show" route. Rails instantiates your controller and attempts to invoke the "show" action on it, passing in an ID of "select".
If you want to add a route in addition to those, you need to explicitly define it, and you should also explicitly state which routes you want if you don't want all seven:
resources :customer_selection, only: %w(index) do
collection { get :select }
# or
# get :select, on: :collection
end
Since you have so few routes, you can also just define them without using resources:
get "/customer_selection" => "customer_selection#index"
get "/customer_select/select"
Note that, in the second route, the "customer_select#select" is implied. In a route with only two segments, Rails will default to "/:controller/:action" if you don't specify a controller/action.

Resources