Ruby on Rails: No routes match for[POST] '/contacts/new' - ruby-on-rails

Rails 5. keep getting the error that route could not be found. What did I do wrong here?
App/views/contacts/new.html.erb
<%= form_for "#contact" do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
routes.rb file
Rails.application.routes.draw do
root to: 'pages#home'
get '/about', to: 'pages#about'
resources :contacts
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
redirect_to new_contact_path, notice: "Message sent."
else
redirect_to new_contact_path, notice: "Error occured."
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
end
contact.rb (model file, blank for now)
class Contact < ActiveRecord::Base
end
I can't figure out why. Thanks in advance.

You have quotes around your #contact variable in your form, try just using the plain #contact variable.

Related

render form_for partial in view

Thank you in advance for any help provided. I've tried researching this a bunch but I can't get it to work.
When trying to render contacts/_new.html.erb inside of pages/home.html.erb
I get "First argument in form cannot contain nil or be empty"
I think it has something to do with which controller Rails is looking in.
Does Rails know to look in my ContactsController even though the main view is coming from the PagesController? I have tried many things and researched this a lot. I've tried locals and changing url and actions. It works when it is not in a partial. It works when I hard code form_for Contact.new.
Thanks again!
_new.html.erb
<%= form_for #contact do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit',class: 'btn btn-default' %>
<% end %>
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
redirect_to root_path, notice: "Message sent."
else
redirect_to root_path, notice: "Error occured."
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
end
Render with:
<%= render new_contact_path %>
in the views/pages/home.html.erb
This is because #contact doesn't exist in your pages_controller.rb, and at the moment to load the contact variable in your form_for it throws this error.
You only have it defined in your contacts_controller but that's not being accessed when you load the pages/home view, it'll go to look for a #contact variable defined in your pages_controller specifically in your home method.
Try adding it in your pages_controller.rb as:
# app/controllers/pages_controller
def home
#contact = Contact.new
end

THE SUBMIT BUTTON

Udemy: Bootcamp course: section: 8 Lecture: 122: SAVING TO THE DATABSE: In the "Contact Us" page I filled in the info, Name: test1, Email: test1#example.com, Comments: test1, as a test, pressed submit, but the button do not submit the info and gives no error message. Where am I going wrong? Any expert advice? Here is my code:
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
flash[:success] = 'Message sent.'
redirect_to new_contact_path
else
flash[:danger] = 'Error occured, message has not been sent.'
redirect_to new_contact_path
end
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :comments)
end
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="well"
<%= form_for #contact do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :comments %>
<%= f.text_area :comments, class: 'form-control' %>
</div>
<%= f.submit 'Submit', class: 'btn btn-default' %>
<% end %>
</div>
</div>
</div>
Im not a rails expert but you can try <%= form_for(#contact, :method => :get) do |f| %> that should get it to work.
In your contact.rb model type the following
class Contact < ActiveRecord::Base
end

DRY controller .valid? for create and update using simple_form

So I've got these views:
new.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Expose Your Hidden Gem</h1>
<%= simple_form_for #place do |f| %>
<%= f.input :name, error: "Name is mandatory" %>
<%= f.input :address %>
<%= f.input :description %>
<br />
<%= f.submit 'Create', class: 'btn btn-primary' %>
<% end %>
</div>
edit.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Edit Your Place</h1>
<%= simple_form_for #place do |f| %>
<%= f.input :name %>
<%= f.input :address %>
<%= f.input :description %>
<br />
<%= f.submit 'Update', class: 'btn btn-primary' %>
<% end %>
</div>
this model:
Place.rb
class Place < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
has_many :photos
geocoded_by :address
after_validation :geocode
validates :name, presence: true
validates :address, presence: true
validates :description, presence: true
end
And finally, places_controller.rb (only showing create and update)
def create
#place = current_user.places.create(place_params)
if #place.save
redirect_to root_path
else
render :new
end
end
def update
#place = Place.find(params[:id])
if #place.user != current_user
return render text: 'Not Allowed', status: :forbidden
end
#place.update_attributes(place_params)
if #place.save
redirect_to root_path
else
render :edit
end
end
But, I'm trying to think DRY and want to know if there is a better way to do a validation for name address and description presence without having the same identical code in both the create and update portions of my controller? I feel like I should just be writing it once...
First, you can refactor your views to use the following structure:
# new.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Expose Your Hidden Gem</h1>
<%= render 'form' %>
</div>
# edit.html.erb
<div class="booyah-box col-xs-10 col-xs-offset-1">
<h1>Edit Your Place</h1>
<%= render 'form' %>
</div>
# _form.html.erb
<%= simple_form_for #place do |f| %>
<%= f.input :name %>
<%= f.input :address %>
<%= f.input :description %>
<br />
<% submit_label = #place.new_record? ? 'Create' : 'Update' %>
<%= f.submit submit_label, class: 'btn btn-primary' %>
<% end %>
And then in your controllers you could refactor to:
def create
#place = current_user.places.new(place_params)
if #place.save
redirect_to root_path
else
render :new
end
end
def update
#place = current_user.places.find(params[:id])
#place.attributes = place_params
if #place.save
redirect_to root_path
else
render :edit
end
end

Ruby Incorrect link generation redirect_to products_path(#product) generate /products.1 instead of /products/1

I'm trying to add a reviews on my single product page. But when I click Submit - It takes me to the /products.1 page, instead of /products/1
class CommentsController < ApplicationController
def create
#product = Product.find(params[:product_id])
#comment = #product.comments.new(comment_params)
#comment.user = current_user
#comment.save
redirect_to products_path(#product)
end
def destroy
end
private
def comment_params
params.require(:comment).permit(:user_id, :body, :rating)
end
end
and the comment.html.erb
<div class="row">
<div class="col-sm-6">
<% if signed_in? %>
<h4>Add a review:</h4>
<%= form_for([#product, #product.comments.build]) do |f| %>
<p>
<%= f.label :body, "Comment" %><br>
<%= f.text_area :body, class: "form-control" %>
</p>
<p>
<%= f.label :rating %><br>
<%= f.text_field :rating, class: "rating form-control" %>
</p>
<p>
<%= f.submit "Submit", class: "btn" %>
</p>
<% end %>
<% end %>
</div>
</div>
Try redirect_to #product instead of redirect_to products_path(#product).
Did you check your routes.rb under config? Try running rake routes in the terminal and you can debug from there.

Ruby on Rails won't render edit page without id

For some reason the edit action won't render i get this error and is using show action instead of edit but the same form works for the render :new action
do not focus on the params[:preview], i am talking about the last render :edit
ActionController::UrlGenerationError in Admin::Blog::Posts#update
No route matches {:action=>"show", :controller=>"admin/blog/posts", :id=>""} missing required keys: [:id]
def edit
#post = Post.find_by_permalink(params[:id])
end
def update
#post = Post.find_by_permalink(params[:id])
if params[:publish]
#post.publish
elsif params[:draft]
#post.draft
end
if params[:preview]
if #post.published?
#post.draft
end
if #post.update(blog_post_params)
flash[:success] = "some text "
redirect_to blog_post_url(#post)
else
render :edit
end
end
if #post.update(blog_post_params)
flash[:success] = "Post was successfully updated."
redirect_to edit_admin_blog_post_url(#post)
else
render :edit
end
end
form
<%= form_for [:admin,:blog, #post] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="large-12 columns">
<div class="field panel">
<%= f.label :title %><br>
<%= f.text_field :title %>
</div>
<div class="field panel">
<%= f.label :description %><br>
<%= f.text_field :description %>
</div>
<div class="actions panel text-right">
<% if #post.published? %>
<%= f.submit "Save Changes",name: "publish", class: "tiny button radius success" %>
<% else %>
<%= f.submit "Publish",name: "publish", class: "tiny button radius success" %>
<% end %>
<%= f.submit 'Mark as Draft', name: "draft", class: "tiny button radius " %>
<% if #post.created_at %>
<%= f.submit 'Preview', name: "preview", class: "tiny button radius warning" %>
<% end %>
<%= link_to 'Back', admin_blog_posts_path, class: "tiny button radius secondary" %>
</div>
<div class="field panel">
<%= f.label :body %><br>
<%= f.cktext_area :body, :height => '800px', :id => 'sometext' %>
</div>
</div>
<% end %>
relevant routes
namespace :admin do
namespace :blog do
get '', to: 'welcome#index', as: '/'
resources :posts
end
end
post model
class Post < ActiveRecord::Base
has_many :tags
has_many :comments
before_validation :generate_permalink
validates :permalink, uniqueness: true
validates :title, presence: true
validates :description, presence: true
def generate_permalink
self.permalink = title.parameterize
end
def to_param
permalink
end
end
I guess i know why you get this error.
In the edit action you use Post.find_by_permalink(params[:id]) to find your post, which returns nil if nothing was found. And since you may change the title attribute, your permalink is updated (i guess), and your post is not found. The controller still renders the action, with nil #post, and cannot generate the url for the form.
Try using Post.find_by_permalink!(params[:id]) instead, and you will get a 404.
I would actually suggest you to use regular find in the admin area, since the permalink might change.

Resources