nesting comments resources in posts resources - ruby-on-rails-4

I'm doing the RoR tutorial on rubyonrails.org and have been doing fine up until adding comments to posts.
When I click through to 'show' a post, I get the following error:
ActionController::UrlGenerationError in Posts#show
No route matches {:action=>"index", :controller=>"comments", :id=>"1", :format=>nil} missing required keys: [:post_id]
I have a show method for posts_controller.rb (see below), and, unless there's a typo on the rails guide (likely, since there are others in other spots), I think there's something going on with my routes.rb.
It says the error occurs around line 25 of /show.html.erb.
Title:
<%= #post.title %>
<p>
<strong>Text:</strong>
<%= #post.text %>
</p>
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([:post, #post.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
<%= link_to 'Edit', edit_post_path(#post) %>
/posts_controller.rb
class PostsController < ApplicationController
def new
#post = Post.new
end
def index
#post = Post.all
end
def show
#post = Post.find(params[:id])
end
def create
#post = Post.new(params[:post].permit(:title, :text))
if #post.save
redirect_to #post
else
render 'new'
end
def edit
#post = Post.find(params[:id])
end
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
routes.rb
Myapp::Application.routes.draw do
resources :posts do
resources :comments
end
root "welcome#index"
end
I think the error has something to do with my routes.rb file, but I can't figure out exactly what. Am I nesting my routes for the comments incorrectly?

Related

Can't route to /logout with Authlogic

I've been trying to set up user authentication in my app using Authlogic, and I'm sure the problem is in my code but I can't seem to find it. When I hit the /login link, all works as expected, but my /logout wants to use GET instead of DELETE.
routing.db
Rails.application.routes.draw do
root 'comments#index'
resources :roles
resources :subjects
resources :comments
resources :topics
resources :users
resources :user_sessions, only: [:create, :destroy]
delete '/logout', to: 'user_sessions#destroy', as: :logout
get '/login', to: 'user_sessions#new', as: :login
end
user_sessions_controller
class UserSessionsController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
before_filter :require_user, :only => :destroy
def new
#user_session = UserSession.new
end
def create
#user_session = UserSession.new(user_session_params)
if #user_session.save
flash[:success] = "Welcome back!"
redirect_to root_path
else
render :action => :new
end
end
def destroy
current_user_session.destroy
flash[:success] = "Goodbye!"
redirect_to root_path
end
private
def user_session_params
params.require(:user_session).permit(:username, :password, :remember_me)
end
end
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= content_for?(:title) ? yield(:title) : "Untitled" %></title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
<%= yield(:head) %>
</head>
<body>
<div id="user_nav">
<% if current_user %>
<span><%= current_user.username %></span>
<%= link_to "Edit profile", edit_user_path(:current) %>
<%= link_to 'Sign Out', logout_path, :method => :delete %>
<% else %>
<%= link_to "Register", new_user_path %>
<%= link_to 'Sign In', login_path %>
<% end %>
</div>
<div id="container">
<% flash.each do |name, msg| %>
<%= content_tag :div, msg, :id => "flash_#{name}" %>
<% end %>
<%= content_tag :h1, yield(:title) if show_title? %>
<%= yield %>
</div>
</body>
</html>
Does anything here look wrong? Here's the error I'm getting:
In your application.html.erb file:
Change:
<%= javascript_include_tag :defaults %>
To:
<%= javascript_include_tag "application" %>
It should work after that!

rails 4 iframe routing error

I am following this tutorial just to learn more about implementing coffeescript.
My model is
class Url < ActiveRecord::Base
validates :url, presence: true
end
controller
class UrlsController < ApplicationController
def new
#shortened_url = Url.new
end
def create
#shortened_url = Url.new(url_params)
if #shortened_url.save
flash[:shortened_id] = #shortened_url.id
redirect_to new_url_url
else
render :action => "new"
end
end
def show
#shortened_url = Url.find(params[:id])
redirect_to #shortened_url.url
end
private
def url_params
params.require(:url).permit(:url)
end
end
end
coffeescript
$(document).ready ->
preview = $("#preview-url")
$('#url_url').keyup ->
current_value = $.trim #value
if current_value is ''
preview.hide().attr 'src', ''
else
preview.show().attr 'src', current_value
app/views/layouts/application.rb
<!DOCTYPE html>
<html>
<head>
<title>Shorty</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<% if flash[:shortened_id].present? %>
<p class='shortened-link'>
The shortened url is available <%= link_to 'here',
url_url(flash[:shortened_id]) %>.
(Right click and copy link to share it).
</p>
<% end %>
<%= yield %>
</body>
</html>
app/views/urls/new.html.erb
<h1>Add a new URL</h1>
<%= form_for #shortened_url do |form| %>
<p>
<%= form.label :url, "Your URL:" %>
<%= form.text_field :url %>
</p>
<% if #shortened_url.errors[:url].any? %>
<p class='error-messages'>
The given url <%= #shortened_url.errors[:url].to_sentence %>.
</p>
<% end %>
<p class='buttons'>
<%= form.submit "Shorten my URL" %>
</p>
<% end %>
<iframe id='preview-url' style='width: 600px; height: 400px; display: none'></iframe>
config/routes.rb
Rails.application.routes.draw do
resources :urls, :only => [:new, :show, :create]
# get '/', to: 'urls#create', as: :new_url_url
root :to => redirect('/urls/new')
end
the error is
No route matches [GET] "/urls/www.rte.ie"
I assume the coffeescript is being executed because the above address is the url I entered inthe text box and the iframe is invisible until an url is provided
It seems you need to add the protocol to the url, otherwise the redirect won't work when you do redirect_to #shortened_url.url in your show action. You can do that in your model with a before_save like this:
class Url < ActiveRecord::Base
before_save :ensure_protocol
private
def ensure_protocol
self.url = "http://#{url}" unless url_protocol_present?
end
def url_protocol_present?
u = URI.parse(url)
u.scheme
end
end
Also, I think you have a typo in your new action: what is new_url in the redirect_to statement?

errors messages doesn't work in HTML ruby code

I am using rails 4.1.6 I looked at the active record validations site and follow their direction, but nothing is displayed in the HTML even if there is an error.
However, when I do it in rails console it works.
post = Post.new #create an empty post to test
post.valid? #false
post.errors.messages #this is successfully generate the error message array
However, it doesn't display any error messages in HTML. In fact "#post.errors" doesn't even run
-Ruby code in html
<%= form_for #post, :method => :post do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :url %>
<%= f.text_field :url %>
<%= f.submit "Submit" %>
<% if #errors.any? %>
<ul>
<% #errors.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<% end %>
-My PostsController
def create
# post = Post.new(title: params[:post][:title], url: params[:post][:url])
post = Post.new(post_params)
if post.save
redirect_to posts_path
else
#errors = post.errors.messages
redirect_to paths_path
end
end
private
def post_params
params.require(:post).permit(:title, :url)
end
-My post model
class Post < ActiveRecord::Base
validates :title, :length => {maximum: 140, minimum:1}, :presence => true
validates :title, :length => {maximum: 2083, minimum:1}, :allow_blank => true
end
When it comes to errors I do like to have a partial so I can keep my errors the same in the whole app like so:
app/views/shared/_errors.html.erb:
<% if object.errors.any? %>
<h5>The <%= t("activerecord.models.#{object.class.to_s.downcase}") %> could not be saved due to the following errors:</h5>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
And then for the views you want the errors to be displayed, just call:
<%= render 'shared/errors', object: #your_object %>
Hope this helps!
thanks for your help. Got some tip from my teacher it work. Simply use flash[:message] and it worked. Sorry for the trouble everyone
-My controller code
def create
post = Post.new(post_params)
if post.save
redirect_to :back
else
flash[:message] = post.errors.messages
redirect_to :back
end
end
-My HTML code
<%= simple_form_for #post, :method => :post do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :url %>
<%= f.text_field :url %>
<%= f.submit "Submit" %>
<%= flash[:message] %>
<% end %>

Ruby on Rails Guides | partial variable - cannot contain nil or be empty

I am following Ruby on Rails Guides and I have an error in rendering partial when I want to create a new article:
First argument in form cannot contain nil or be empty
Marked error is from partial _form.html.erb located in the same place as index:
<%= form_for #article do |f| %>
index.html.erb has link:
<%= link_to 'New article', new_article_path %>
controller:
def create
#article = Article.new(article_params)
#article.save
redirect_to #article
end
form partial:
<%= form_for #article do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %><br>
</p>
<% end %>
new.html.erb which renders partial:
<h1>New article</h1>
<%= render 'form' %>
<%= link_to 'Back', articles_path %>
your controller needs a new method
def new
#article = Article.new
end
that way there's an #article object that the form_for can reference.
When you follow a new link, the new action is executed and the form is displayed. It's only when the form is submitted that the create action is executed.

NoMethodError in Posts#show undefined method `post_comments_path'

I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is
undefined method `post_comments_path' for #<#<Class:0x2aef820>:0x2bd7df8>
Extracted source (around line #25):
<h2>Add a comment:</h2>
<%= form_for([#post, #post.comments.build]) do |f| %>...here it is line number 25
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
I have two model
post.rb
class Post < ActiveRecord::Base
has_many :comments
validates :title, presence: true,
length: { minimum: 5 }
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :post
end
I have two controllers
posts_controller.rb
class PostsController < ApplicationController
def new
#post=Post.new
end
def show
#post = Post.find(params[:id])
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(params[:post].permit(:title, :text))
redirect_to #post
else
render 'edit'
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to posts_path
end
def create
#post = Post.new(post_params)
# it will also works #post=Post.new(params[:post].permit(:title,:text))
if #post.save
redirect_to #post
# or this command also works redirect_to action: :show, id: #post.id
else
render 'new'
end
end
def index
#posts = Post.all
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end
comments_controller.rb
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(params[:comment].permit(:commenter, :body))
redirect_to post_path(#post)
end
end
my routes.rb file is
Blog::Application.routes.draw do
resources :posts do
resources :comments
end
I have two migration files
create_posts.rb
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :title
t.text :text
t.timestamps
end
end
end
create_comments.rb
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :post
#above line sets foreign key column for the association between the two models.
t.timestamps
end
#and bellow add_index line sets up an index for this association column.
add_index :comments, :post_id
end
end
my show.html.erb file is
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<p>
<strong>Text:</strong>
<%= #post.text %>
</p>
<h2>Comments</h2>
<% #post.comments.each do |comment| %>
<p>
<strong>Commenter:</strong>
<%= comment.commenter %>
</p>
<p>
<strong>Comment:</strong>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([#post, #post.comments.build]) do |f| %>
<p>
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Edit Post', edit_post_path(#post) %> |
<%= link_to 'Back to Posts', posts_path %>
I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is I used associations in the models whenever I am applying associations I am getting problem ,I am new to ruby as well as rails.I am using Rails4,Eclipse,Windows Xp(sp3) and mysql5.6 ,I am getting the above error when I want clicked the show link the error is
I have a feeling you missed the part about nested resources. As in:
resources :posts do
resources :comments
end
This means the routes generated by resources :comments are nested within your posts, which results in URLs like this:
/posts/1/comments