NoMethodError on section 5.7 of Rails Guide - ruby-on-rails

I'm following the Getting Started tutorial for Rails 4.0.0 located here:
http://guides.rubyonrails.org/getting_started.html
I'm at the point in section 5.7 where I'm supposed to be getting the ActiveModel::ForbiddenAttributes error. Instead, I get this error:
NoMethodError in Posts#show
Showing C:/Rails/blog/app/views/posts/show.html.erb where line #8 raised:
undefined method `text' for nil:NilClass
Extracted source (around line #8):
5
6 <p>
7 <strong>Text:</strong>
8 <%= #post.text %>
9 </p>
Despite this, I believe the posts are being created, since the ids are being incremented each time I submit the form. I am brand new to Rails, and have attempted to exactly follow the instructions.
I'm running Windows 7 x64, with Ruby 1.9.3 and Rails 4.0.0.
Here are some relevant files; please let me know if any other are required.
posts_controller.rb:
class PostsController < ApplicationController
def new
end
def create
#post = Post.new(post_params)
#post.save
redirect_to #post
end
private
def post_params
params.require(:post).permit(:title, :text)
end
def show
#post = Post.find(params[:id])
end
end
show.html.erb:
<p>
<strong>Title:</strong>
<%= #post.title %>
</p>
<p>
<strong>Text:</strong>
<%= #post.text %>
</p>
new.html.erb
<h1>New Post</h1>
<%= form_for :post, url: posts_path 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 %>
</p>
<% end %>

Just write down show method after create method, as your show method is below the keyword private it is taking private as a Access Modifier and hence can't access directly through browser
class PostsController < ApplicationController
def new
end
def create
#post = Post.new(post_params)
#post.save
redirect_to #post
end
def show
#post = Post.find(params[:id])
end
private
def post_params
params.require(:post).permit(:title, :text)
end
end

I was having the same problem with the tutorial (which at this date (11/18/14) uses 'articles' instead of 'posts'), and found the solution to be the placement of the following "def" block in articles_controller.rb:
def show
#article = Article.find(params[:id])
end
Here's what it looks like for me:
class ArticlesController < ApplicationController
def new
end
def create
#article = Article.new(article_params)
#article.save
redirect_to #article
end
def show
#article = Article.find(params[:id])
end
private
def article_params
params.require(:article).permit(:title, :text)
end
end

Related

action create couldn't be found for PostsController

I'm following a rails tutorial and need some help to proceed further. Problem is, once I fill out the form which has a title,body fields and hit submit, it has to redirect to the show.html.erb page instead it throws an error.
Error: The action 'create' could not be found for PostsController
routes.rb
Rails.application.routes.draw do
get "/pages/about" => "pages#about"
get "/pages/contact" => "pages#contact"
get "/posts" => "posts#index"
post "/posts" => "posts#create"
get "/posts/show" => "posts#show", as: :show
get "/posts/new" => "posts#new"
end
posts_controller_tests.rb
require 'test_helper'
class PostsControllerTest < ActionController::TestCase
def index
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.save
redirect_to show_path
end
def show
end
private
def post_params
params.require(:post).permit(:title, :body)
end
end
new.html.erb
<h1>Create a new blog post</h1>
<div class="form">
<%= form_for Post.new do |f| %>
<%= f.label :title %>: <br>
<%= f.text_field :title %> <br> <br>
<%= f.label :body %>: <br>
<%= f.text_area :body %> <br> <br>
<%= f.submit %>
<% end %>
</div>
Any help on this would be appreciated.
Note: You are using posts_controller_tests.rb not posts_controller.rb. You are putting your controller code in test controller.
Try to move the code in app/controllers/posts_controller.rb:
class PostsController < ApplicationController
def index
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.save
redirect_to show_path
end
def show
end
private
def post_params
params.require(:post).permit(:title, :body)
end
end
Your create action always redirects you to the show action. It doesn't matter if your model was saved or not.
You have to check if the model was saved or not:
def create
#post = Post.new(post_params)
if #post.save
flash[:success] = 'Successfully saved'
redirect_to #post
else
render 'new'
end
end
If it wasn't saved, it renders the new action again.
Change your routes.rb to this:
Rails.application.routes.draw do
get "/pages/about" => "pages#about"
get "/pages/contact" => "pages#contact"
resources :posts
end
Moreover you should inherit your controller from ActionController::Base
so change first line of your controller to
class PostsController < ActionController::Base
and move the controller to app/controllers/posts_controller.rb

ActiveModel::ForbiddenAttributesError in PostsController#create

I've started learning Ruby on Rails.
Iam getting below error: ActiveModel::ForbiddenAttributesError in PostsController#create
Here is the code:
posts_controller.rb
class PostsController < ApplicationController
def index
#posts = Post.all
end
def show
#post = Post.find params[:id]
end
def new
#post = Post.new
end
def create
#post = Post.create(params[:post]) // Its showing me error here
if #post.save
redirect_to posts_path notice: "Your Post was saved"
else
render "new"
end
end
end
new.html.erb
<h1> Add a New Post </h1>
<%= form_for #post do |f| %>
<p>
<%= f.label :title %><b/>
<%= f.text_field :title %><b/>
</p>
<p>
<%= f.label :content %><b/>
<%= f.text_area :content %><b/>
</p>
<%= f.submit "Add a New Post" %>
<% end %>
post.rb
class Post < ActiveRecord::Base
validates_presence_of :title, :content
end
Please tell me what went wrong. BTW, iam using Rails4
In rails4 there is strong parameters so you can't do this:
#post = Post.create(params[:post])
You need
#post = Post.create(post_params)
Where post_params is a method in your controller:
private
def post_params
params.require(:post).permit!
end
permit! will permit anything. You can limit it though to what you want to allow for example params.require(:post).permit(:title, :content)
You have to use strong params for rails 4 to solve this problem.
Docs: http://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters
def post_params
params.require(:post).permit(:title, :content)
end
and in create action use: Post.create(post_params)
You have to use strong params always when you create or update a record.

Extra line breaks with simple_format

To practice Ruby on Rails, I am creating a blog which includes a text area (following Mackenzie Child's tutorial). Unfortunately, line breaks are included every time I press enter. How can I remove the extra line breaks?
show.html.erb
<h1><%= #post.title %></h1>
<p><%= simple_format(#post.body) %></p>
_form.html.erb
<div class="form">
<%= form_for #post do |f| %>
<%= f.label :title %><br>
<%= f.text_field :title %><br>
<br>
<%= f.label :body %><br>
<%= f.text_area :body %><br>
<br>
<%= f.submit %>
<% end %>
</div>
posts_controller.rb
class PostsController < ApplicationController before_action :authenticate_user!, except: [:index, :show]
def index
#posts = Post.all.order('created_at DESC')
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
#post.save
redirect_to #post
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, :body))
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, :body)
end
end
So I type the following into the text area:
for j in 1..array.length-1
key = array[j]
i = j - 1
But this is what posts:
for j in 1..array.length-1
key = array[j]
i = j - 1
And if remove simple_format, it removes all new lines, which I don't want either.
In the developer tools:
<p>
" for j in 1..array.length-1
"
<br>
" key = array[j]
"
<br>
" i = j - 1
"
<br>
I’m going to assume, that because you are wrapping the body content in show.html.erb, that you don’t mind the data in your database but just want to clean it up to present it.
Have you tried:
<p><%= strip_tags #post.body %></p>
Rails API Reference
I could be misunderstanding the question, but I think you're getting confused about the purpose of simple_format.
simple_format takes some text that has line breaks in it and formats it as basic HTML by replacing 2 or more line breaks as paragraphs and single line breaks as <br> tags. This is what you would use to display a post to a visitor to the blog.
When you want the text of an existing blog post in a textarea then you want to leave the line breaks in the text intact, which is achieved using <%= f.text_area :body %> without wrapping in a call to simple_format.

First argument in form cannot contain nil or be empty rails 4 Associated models

I have a provider model which has many comments. I have a current setup working with the form being:
views/comments/_form.html.erb
<%= form_for([#provider, Comment.new] ) do |f| %>
<%= f.text_area :body, cols: 30, rows: 4, class: 'form-control' %>
<%= f.hidden_field :user_id, value: current_user.id, class: "form-control" %>
<div>
</br>
<%= f.submit :post, class: 'btn btn-primary btn-lg' %>
</div>
<% end %>
But I dont think its right from what iv seen around it should be
<%= form_for([#provider, #comment[) do |f| %>
but this method I get the following error
First argument in form cannot contain nil or be empty
I access my comments form from within my provider show.html.erb like this
<%= render 'comments/form', provider: #provider %>
My comments views are just _form.html.erb and _comments.html.erb which lists all the comments for a given provider.
My comments_controller.rb is as follows
class CommentsController < ApplicationController
before_action :set_provider
def new
#comment = Comment.new
end
def create
#provider = set_provider
#comment = #provider.comments.create!(comment_params)
redirect_to #provider
end
def destroy
#provider = set_provider
#comment = Comment.find(params[:id])
#comment.destroy
redirect_to #provider
end
private
def set_provider
#provider = Provider.find(params[:provider_id])
end
def comment_params
params.require(:comment).permit(:body, :user_id)
end
end
If anyone point me in the right direction that would be very much appreciated.
Found the issue.
Because I was showing the Comments in the show action of my provider model I needed this in the Provider
def show
#comment = Comment.new
#provider = find_provider
end
Works perfectly now.

can some one tell me what the correct syntax of the ruby posts GET is?

I am trying to write a rails app and it keeps bombing on this one line of code in my controller.rb file:
posts GET /posts(.:format) posts#show
Can some one help me?
I am running ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-darwin12.4.0]
with rails 3.2.13
UPDATE
I took out the line of code above and now I can't get rails to post the value (tag) of the selected check box. Can I get some guidance?
Here is my posts_controller.rb file:
class PostsController < ApplicationController
def new
end
def create
#post = Post.new(params[:post].permit(:check_box, :label))
#post.save
redirect_to #post
end
def show
#post = Post.find(params[:id])
end
def index
#posts = Post.all
end
private
def post_params
params.require(:post).permit(:check_box, :label)
end
end
Here is my new.html.erb file:
<h1>SWORD Mock Device Page</h1>
<%= form_for :post, url: posts_path do |f| %>
<p>
<h2>Android Phones</h2>
<%= f.check_box(:razr_max1) %>
<%= f.label(:razr_max1, "Droid Razr Max #1") %>
</p>
<p>
<%= f.check_box(:galaxyS2) %>
<%= f.label(:galaxyS2, "Samsung Galaxy S2") %>
</p>
<p>
<h2>Android Tablets</h2>
<%= f.check_box(:asusprime3) %>
<%= f.label(:asusprime3, "Asus Transormer Prime #3") %>
</p>
<p>
<%= f.check_box(:motoxoom1) %>
<%= f.label(:motoxoom1, "Motorola Xoom #1") %>
</p>
<p>
<%=f.submit "Select" %>
</p>
<% end %>
here is my routes.rb:
SWORDMockDev::Application.routes.draw do
resources :posts
root to: "landing#index"
end
and my show.html.erb:
<p>
<strong>Device:</strong>
<%= #post.title %>
</p>
Any help is greatly appreciated!!
Thanks!!
ironmantis7x
Instead of:
def create
#post = Post.new(params[:post].permit(:check_box, :label))
#post.save
redirect_to #post
end
You can do:
def create
#post = Post.new(post_params)
#post.save
redirect_to #post
end
The label is not going to submit in the post, only the value of the checkbox
I recommend you to use pry https://github.com/pry/pry and in the controller in the create you can do:
def create
binding.pry
#post = Post.new(post_params)
#post.save
redirect_to #post
end
And you can see what comes in the params, and what's going on. Also checkout your routes and see if everything is ok with:
rake routes

Resources