Ruby On Rails adding new page after scaffolding - ruby-on-rails

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

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: What to call in view?

I have a next method in the model.
def self.next(comment, key = :id)
self.where("#{key} > ?", comment.send(key)).first
end
In my view I can say for example: (does not work)
= link_to "next", #comment.next(#comment)
What's the correct way to call this method?
routes.rb:
Rails.application.routes.draw do
resources :articles do
resources :comments do
end
end
end
You've defined next as a class method (vs an instance method), so you need:
= link_to "next", Comment.next(#comment)
If you want to be able to call #comment.next, define the instance method as:
def next(key = :id)
Comment.where("#{key} > ?", self.send(key)).first
end
It is not good style that the model knows this, you should put it in the controller. You should try a gem called kaminari, this gem lets you paginate over the elements, so in your comments controller you could have something like:
def show
#comment = Comment.order(id: :asc).page(params[:page]).per(1)
end
Then in your view, by just adding this kaminari helper:
<%= paginate #comment %>
You get the pagination bar below and everything works fine (gem's magic).
If you don't like this you could try to add that next method in the controller or find both next and current elements and link to the next element.
In my opinion the model is just a class that knows how to save and get information from the database and maybe some calculations with it's information, so all that logic related to the view should be elsewhere.

Rails 4 Routing - undefined local variable

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

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.

How to show information of specific beer inside a beercase

I have an application where it has beer, beercase, and drinker models on it. The beer inside the beercase can be assorted.
I'm bit struggling in how to show the information of a specific beer inside a beer case. Currently I listed all the beers inside the beercase of the drinker so I have a list of beer partial _beerlist:
<h1>beer you added</h1>
<% #drinker.beercase_line_items.each do |beer|%>
<p><%= link_to beer.beer.name, specificbeer_drinker_drinker_beercase_pages_path(#drinker) %></p>
<%end%>
I tried doing this but
<h1>beer you added</h1>
<% #drinker.beercase_line_items.each do |beer|%>
<p><%= link_to beer.beer.name, specificbeer_drinker_drinker_beercase_pages_path(#drinker,beer) %></p>
<%end%>
gives me a beer.20 at the middle of the URL, not beer/20 which I wanted for him to produce. Am I doing this right?
routes
resources :drinker do
resources :pages do
collection do
get :beercaselist # Name of beercase that can be added example:extrabucket-beercase
get :beercase # Show the beercase information and it has a link to add beer
end
end
resources :drinker_beercase # Controller to add what beercase that the drinker added
resources :drinker_beercase_pages do # Static page controller
collection do
get :beerlist # Show the beerlist
get :specificbeer # Show the specificbeer
end
end
resources :beercase_line_items # Controller to add what beer and what beercase
end
Okay, so bear with me, I don't think I fully understand your routes, but I think this may be your problem:
Your specificbeer_drinker_drinker_beercase_pages route looks like this:
/drinker/:drinker_id/drinker_beercase_pages/specificbeer(.:format)
That only has the :drinker_id parameter in it. This route is meant for displaying a list of specificbeers, not a single specific beer. If you change your routes file to look like this:
resources :drinker_beercase # controller to add what beercase that the drinker added
resources :drinker_beercase_pages do #static page controller
collection do
get :beerlist # show the beerlist
end
member do
get :specificbeer # show the specificbeer
end
end
end
Then the specificbeer_drinker_drinker_beercase_page will lead to this url:
/drinker/:drinker_id/drinker_beercase_pages/:id/specificbeer(.:format)
I'm not sure exactly if that's what you're going for, but hopefully it helps lead you in the right direction.

Resources