Rails URL Generation Error but route exists - ruby-on-rails-4

Making a basic phonebook app and made some changes while figuring out the has_many and belongs_to relationships. I must have broke something because I have no idea why I'm getting this error. When I access my root, I get the following-->
ActionController::UrlGenerationError in ContactsController#index
No route matches {:action=>"show", :controller=>"contacts"} missing required keys: [:id]
The error shows mistakes in lines:
app/views/contacts/index.html.erb:10:in `block in _app_views_contacts_index_html_erb___2771775118522806317_70170309989460'
app/views/contacts/index.html.erb:7:in `_app_views_contacts_index_html_erb___2771775118522806317_70170309989460'
This is my contacts/index.html.erb
<p id="notice"><%= notice %></p>
<% if user_signed_in? %>
<h1>Listing Contacts</h1>
<% #contacts = current_user.contacts %>
<% #contacts.each do |contact| %>
<div class="link row clearfix">
<h2>
<%= link_to contact.name, contact_path %>
</h2>
</div>
<% end %>
<% end %>
<%= link_to "New Contact", new_contact_path %>
<% else %>
<h5> Welcome. Make an account or sign in above! </h5>
<% end %>
This is my config/routes
Rails.application.routes.draw do
resources :controllers
devise_for :users
resources :contacts so
resources :numbers
end
end
end
This is my contacts/show.html.erb
<div class="page-header">
<h1><%= #contact.name %><br> </h1>
</div>
<p>
<strong>Name:</strong>
<%= #contact.name %>
</p>
<p>
<strong>Email:</strong>
<%= #contact.email %>
</p>
<br>
<%= link_to 'Edit', edit_contact_path(#contact) %> |
<%= link_to 'Back', contacts_path %>
The output of my rake routes:
contacts GET /contacts(.:format) contacts#index
POST /contacts(.:format) contacts#create
new_contact GET /contacts/new(.:format) contacts#new
edit_contact GET /contacts/:id/edit(.:format) contacts#edit
contact GET /contacts/:id(.:format) contacts#show
PATCH /contacts/:id(.:format) contacts#update
PUT /contacts/:id(.:format) contacts#update
DELETE /contacts/:id(.:format) contacts#destroy
As you can see, I have a route for contacts#show so that's not the mistake. I'm unclear as to what it could be. Any ideas?

Seems like you're missing :id from the contact_path.
In contacts/index.html.erb, change this:
<%= link_to contact.name, contact_path %>
to this:
<%= link_to contact.name, contact_path(contact.id) %>

Related

Ruby on rails Tutorial Missing partial articles/_form

Hi I have just started using Ruby on rails and have been following the tutorial # http://guides.rubyonrails.org/getting_started.html.
The problem I have got, is with 5.12 Using partials to clean up duplication in views.
I am getting the error ActionView::MissingTemplate in Articles#new.
It is looking for _form.html.erb , which is in the directory /app/views/articles/. So not sure why it cannot find it.
articles controller for new
def new
#article = Article.new
end
articles view for new
<h1>New article</h1>
<%= render 'form' %>
<%= link_to 'Back', articles_path %>
articles view for _form.html.erb
<%= form_for #article do |f| %>
<% if #article.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#article.errors.count, "error") %> prohibited
this article from being saved:
</h2>
<ul>
<% #article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
< % end %>
Any help would be appreciated, need to know how to solve before going on to next part.
Hi I have got it to work by renaming _form.html.erb to_form as the error is looking for /apps/views/_form. I don't know if this is the correct way to solve the problem, as its says in the tutorial to name the file _form.html.erb.
would this cause issues in future doing it this way?
Check the file name, maybe you copied it wrong
I changed the file name to '_form.erb' and it worked. Still puzzled why the full suffix of 'html.erb' didn't work.

Rails: Accessing nested form data in a view (preview page)

Users can make a reservation, and each reservation can have multiple occurrences. After they've entered their data, they get a preview page to confirm the information before it's saved to the database. The occurrence information is being passed to the preview page. I can see it in the parameter dump at the bottom of the page. I can't seem to access it to display it to the user.
Here's my code:
reservations_controller.rb
def new
#reservation = Reservation.new
#occurrence = #reservation.occurrence.build
end
def preview
if params[:reservation]
#reservation = Reservation.new(reservation_params)
#occurrence = #reservation.occurrence.build(params[:occurrence])
end
end
private
def reservation_params
params.require(:reservation).permit(:title, :description, :is_public, :is_internal, :internal_organization, :contact_name,
:contact_phone, :contact_email, :contact_present, :contact_present_name,
:contact_present_phone, :contact_present_email, :notes)
end
reservations/new.html.erb (I've put some blank lines around the nested form to make it easier to find):
<div id="addReservationForm_container" class="addReservationFormContainer formContainer">
<%= form_for #reservation, :url => preview_path, :html => { :method => :get } do |f| %>
<% if #reservation.errors.any? %>
<div class="error">
Please address the <%= "#{'error'.pluralize(#reservation.errors.count)}" %> below to submit this reservation.
</div>
<% end %>
<%= field_set_tag 'Reservation Information' do %>
<div class="formField paragraph <%= 'error' if #reservation.errors.include?(:title) %>">
<%= f.label :title, 'Title:' %>
<%= f.text_field :title, size: "40", class: (#reservation.errors.include?(:title) ? 'error' : '') %>
</div>
<div class="formField">
<%= f.label :description, 'Enter a short description of the event:' %>
<%= f.text_area :description, size: "60x6" %>
</div>
<div class="formField">
<%= f.label :is_public do %>
Should this event be listed on public calendars?
<%= f.select :is_public, options_for_select([['Yes', true], ['No', false]]) %>
<% end %>
</div>
<hr />
<div class="formField">
<%= f.label :is_internal do %>
Is this reservation for a related event?
<%= f.select :is_internal, options_for_select([['Yes', true], ['No', false]]) %>
<% end %>
</div>
<div class="internalDetails formField <%= 'error' if #reservation.errors.include?(:internal_organization) %>">
<%= f.label :internal_organization, 'Please enter the name of the department, organization, or club hosting the event:' %>
<%= f.text_field :internal_organization, size: '40', class: (#reservation.errors.include?(:internal_organization) ? 'error' : '') %>
</div>
<% end %>
<%= field_set_tag 'Date and Time' do %>
<div class="paragraph">
Select the date(s) and time(s) you want to reserve:
<div class="formField paragraph">
<%= f.fields_for :occurrences do |o| %>
<%= o.text_field :start_date, class: 'datepicker' %>
<%= o.select :end_date, options_for_select(create_hours(:start_time => 7.5.hours, :end_time => 21.hours, :increment => 15.minutes)) %>
<% end %>
</div>
</div>
<% end %>
<%= field_set_tag 'Contact Information' do %>
<div class="paragraph">
Please enter the contact information of the person responsible for the reservation:
</div>
<div class="formField paragraph <%= 'error' if #reservation.errors.include?(:contact_name) %>">
<%= f.label :contact_name, 'Name:' %>
<%= f.text_field :contact_name, size: "40", class: (#reservation.errors.include?(:contact_name) ? 'error' : '') %>
</div>
<div class="formField paragraph <%= 'error' if #reservation.errors.include?(:contact_phone) %>">
<%= f.label :contact_phone, 'Phone:' %>
<%= f.text_field :contact_phone, size: "40", class: (#reservation.errors.include?(:contact_phone) ? 'error' : '') %>
</div>
<div class="formField paragraph <%= 'error' if #reservation.errors.include?(:contact_email) %>">
<%= f.label :contact_email, 'E-mail:' %>
<%= f.text_field :contact_email, size: "40", class: (#reservation.errors.include?(:contact_email) ? 'error' : '') %>
</div>
</div>
<% end %>
<%= field_set_tag 'Additional Information' do %>
<div class="internalDetails formField">
<%= f.label :notes, 'Please enter any additional information or instructions:' %>
<%= f.text_area :notes, size: "60x6" %>
</div>
<% end %>
<%= f.submit 'Continue' %>
<% end %>
</div>
The code below is where I can't seem to display the information from the occurrences nested form.
reservations/preview.html.erb
<div class="paragraph">
Please look over the information you entered for your reservation, and then click either
the "Submit Reservation" button to submit your request, or the "Make Changes" button to
return to the previous form and edit the request.
</div>
<div style="margin-left: 3em;">
<div class="paragraph">
<div> <%= #reservation.title %></div>
<div> <%= #occurrence.start_date %></div>
<div> <%= #reservation.contact_name %> (<%= #reservation.contact_email %>)</div>
<div> <%=#reservation.contact_phone %></div>
</div>
</div>
reservation.rb
has_many :occurrence
accepts_nested_attributes_for :occurrence, :reject_if => :all_blank
I'm new to Rails, so it wouldn't surprise me to find I have multiple things wrong here.

Adding space between labels and fields

In my Rails app, the labels for the fields on the login page are way too close to the fields themselves, making it look cramped. I want to add space between them, but am not sure how.
I have Rails 4 with simple_form, bootstrap 3, and devise installed.
This is my app/views/devise/sessions/new.html.erb code:
<div class="row">
<div class="col-xs-4">
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name), html: {class: "well"}) do |f| %>
<fieldset>
<legend>Log in</legend>
<%= f.input :email %>
<%= f.input :password %>
<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.input :remember_me, as: :boolean %>
</div>
</fieldset>
<% end -%>
<div class="actions">
<%= f.button :submit, "Log in" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
<div class="col-xs-8">
<h2>Signing in is easy and secure</h2>
</div>
</div>
And here is the entire github repo: https://github.com/yamilethmedina/wheels_registration
I've been looking in my bootstrap.css file and can't find relevant classes. What do you think I should do next?
You could add your own label with space after the custom label.
<%= f.input :email, label: 'Email ' %>
<%= f.input :password, label: 'Password ' %>
Or you could use tools like chrome dev tools to inspect the label element to see what class the labels are given and then add some custom css. example .label-class { margin-right: 10px; }

How do you use Active Record Enum Radio Buttons in a form?

In my app, there is a comment section on articles. I'd like the user to have the ability to comment with 3 different options. To activate this, I am using an Active Record Enum. Please note that the comment sections is nested under the articles.
resources :articles, only: [:index, :show] do
resources :comments
end
Migration:
class AddEnumToCommentModel < ActiveRecord::Migration
def change
add_column :comments, :post_as, :integer, default: 0
end
end
Comment model:
enum post_as: %w(username, oneliner, anonymous)
I attempted to add this to the content view, but lost. I am guessing I also have to do something in my controller but not sure.
Attempted view :
<%= form_for([#article, #comment]) do |f| %>
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% #comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<h3>Fill in your comment</h3>
<%= f.label :content %><br>
<%= f.text_area :content %>
</div>
<div class="post_as">
<h3> Choose how you want to post your comment :</h3>
<%= f.input :content, post_as: ???, as: :radio %>
</div>
<br>
<div class="actions">
<%= f.submit %>
</div>
<br>
<% end %>
Rails creates a class method using the pluralized attribute name when you use enum. The method returns a key value pair of strings you've defined and what integers they map to. So, you could do something like this:
<% Comment.post_as.keys.each do |post_as| %>
<%= f.radio_button :post_as, post_as %>
<%= f.label post_as.to_sym %>
<% end %>
There's also collection_radio_buttons, which is more succinct than the other options.
<%= f.collection_radio_buttons :post_as, Comment.post_as, :second, :first %>
Those last two arguments specify how to get the input's value and label text. In your example Comment.post_as produces a hash of enum key names to the underlying integer, so we can grab those using :second for the integer and :first for the name — easy!
Here's what that produces:
<input type="radio" value="0" name="comment[post_as]" id="comment_post_as_0">
<label for="comment_post_as_0">username</label>
# Etc.
You can also customize the HTML by passing a block, which is my preferred way to create enum radio buttons with clickable labels:
<%= f.collection_radio_buttons :post_as, Comment.post_as, :second, :first do |b|
b.label { b.radio_button + b.text }
end %>
An addition to xxyyxx's answer, if you want the labels to be clickable as well:
<% Comment.post_as.keys.each do |post_as| %>
<%= f.radio_button :post_as, post_as %>
<%= f.label "#{:post_as}_#{post_as.parameterize.underscore}", post_as %>
<% end %>
In the view instead of
<%= f.input :content, post_as: ???, as: :radio %>
you could have
<%= f.radio_button(:post_as, "username") %>
<%= label(:post_as, "Username") %>
<%= f.radio_button(:post_as, "oneliner") %>
<%= label(:post_as, "Oneline") %>
<%= f.radio_button(:post_as, "anonymous") %>
<%= label(:post_as, "Anonymous") %>
Source: http://guides.rubyonrails.org/form_helpers.html#radio-buttons

Rails: Render for nested forms

I have a nest form that is working great. The form is basically a customer with addresses.
I am trying to render a partial at both the customer and address level to indicate who created each record and who was the last person to update the record.
My view code is:
<%= form_for(#customer) do |f| %>
<%= render 'cust_fields', f: f %>
<%= render 'layouts/audit', audit: #customer %>
<strong>ADDRESSES:</strong>
<hr />
<%= f.fields_for :addresses do |a| %>
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: :addresses %>
<% end %>
<% end %>
The code in question is <%= render 'layouts/audit', audit: :addresses %>
This is throwing the the error:
undefined method `created_by' for :addresses:Symbol
I have tried to change :addresses to #customer.addresse but that doesn't work either. Why?
My partial code is:
<% created_user = User.find(audit.created_by) %>
<% updated_user = User.find(audit.updated_by) %>
<div class="row audit-info">
<small>
<div class="pull-left">
Created by: <%= created_user.name %>
</div>
<div class="pull-right">
Last updated by: <%= updated_user.name %>
</div>
</small>
</div>
Both the customers and addresses table have created_by and updated_by columns.
Any help would be much appreciated.
I was able to get this working by introducing the following code in my view:
<% for i in 1..#customer.addresses.size %>
<%= f.fields_for #customer.addresses[i-1] do |a| %>
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: #customer.addresses[i-1] %>
<% end %>
<% end %>
Actually, the above didn't work since I was double counting the children records.
What did work (after some more research) was the following:
<%= f.fields_for :addresses do |a| %>
<div class="deleterow">
<%= render "address_fields", f: a %>
<%= render 'layouts/audit', audit: #customer.addresses[a.index] %>
</div>
<% end %>
The key was using a.index, which can be seen on line 4.