Undefined method for nil - ruby-on-rails

I'm trying to finish the codecademy ruby on rails track. I'm getting this error:
Showing /home/ccuser/workspace/learn-rails_innovation-cloud/innovation
cloud/app/views/signups/new.html.erb where line #41 raised:
undefined method `content' for #<Signup id: nil, email: nil, created_at: nil, updated_at: nil>
Extracted source (around line #41):
<%= form_for(#signup) do |f| %>
<div class="field">
<%= f.label :message %><br>
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit "Create" %>
Here's my controller:
class SignupsController < ApplicationController
def new
#signup = Signup.new
end
end
And finally my migration file:
class CreateSignups < ActiveRecord::Migration
def change
create_table :signups do |t|
t.text :email
t.timestamps
end
end
end
Any insight is appreciated to understand what I'm doing wrong.

content field is missing in your signups table. Please add using migration.

Your form code should look like:
<%= form_for(#signup) do |f| %>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit "Create" %>
And it should work now.

Related

ArgumentError in StaticPages#home

I noob in Rails. I use rails 4.2.4. I have a problem with my contact form. I have an error: First argument in form cannot contain nil or be empty on the 3 line of this code (contact_form.html.erb):
<div class="all-banners-width">
<figure class="green-background">
<%= form_for #contact_form do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :phone %><br>
<%= f.text_field :phone %>
</p>
<p>
<%= f.label :email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_field :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
</figure>
</div>
My contact_form_controller.rb is:
class ContactFormController < ApplicationController
def contact_form
#contact_form = ContactForm.new
end
def create
#contact_form = ContactForm.new(contact_form_params)
#contact_form.save
redirect_to root_path, notice: "Saved"
end
private
def contact_form_params
params.require(:contact_form).permit(:name, :phone, :email, :text)
end
end
My DB migration file is:
class CreateContactForms < ActiveRecord::Migration
def change
create_table :contact_forms do |t|
t.string :name
t.string :phone
t.string :email
t.string :text
t.timestamps null: false
end
end
end
If I change 3rd line from contact_form.html.erb to the next:
<%= form_for :contact_form do |f| %>
then I have not an error, but anyway contact form does not work and there are not any errors I can see.
Can somebody help me? I have not idea, where is problem.
You miss action new in controller:
def new
#contact_form = ContactForm.new
end
your template is rendered with #contact_form = nil.

nomethoderror in contacts#new making contactform in ruby

I am new to ruby on rails and i am currently stuck trying to create a contact form.
I get the report saying : undefined method `name' for #, but in the i did create the method for name :
create_table :contacts do |t|
t.string :name
I'v tried to fix this error so i can preview the page, but i keep getting an error. I hope one of you can help me, thanks in advance!
NoMethodError in Contacts#new
Showing /home/nitrous/workspace/simplecodecast_saas/app/views/contacts/new.html.erb where line #7 raised:
undefined method `name' for #<Contact id: nil>
Extracted source (around line #7):
<%= form_for #contact do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %> <---- (This is line 7)
</div>
<div class="form-group">
Rails.root: /home/nitrous/workspace/simplecodecast_saas
Application Trace | Framework Trace | Full Trace
app/views/contacts/new.html.erb:7:in `block in _app_views_contacts_new_html_erb__2291340040590759835_34535240'
app/views/contacts/new.html.erb:4:in `_app_views_contacts_new_html_erb__2291340040590759835_34535240'
Request
Parameters:
None
Toggle session dump
Toggle env dump
Response
Headers:
None
My routes.rb code:
Rails.application.routes.draw do
resources :contacts
get '/about' => 'pages#about'
root 'pages#home'
and my contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
end
end
I added this to my model: contact.rb
class Contact < ActiveRecord::Base
end
And the db file:
class CreateContacts < ActiveRecord::Migration
def change
create_table :contacts do |t|
t.string :name
t.string :email
t.text :comments
t.timestamps
end
end
end
and last my html page
<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>
I found a fix.
I ran the rake db:rollback cmd and then the rake db:migrate.
Now it is working.
Sorry for wasting your time :) Hopefully someone else can benifit from this answer!

Rails 4 Integer number field returns string

When I enter something into a number_field and post the form to the controller, Rails can't save because i have a numericality validation:
validates :rating, numericality: { greater_than: 0, less_than: 6 }
I debugged the controller by this piece of code:
raise "It exploded into pieces!" unless #comment.save
The exception I used for debugging said that my :rating was a string instead of an integer. Before this, i rendered the json errors for #comment and that said that :rating was not a number.
These are very useful to spot the problem, but I can't find any solutions to fix the problem. I checked the database schema and it says that :rating should be an integer, as in:
t.integer "rating"
I don't know what to do at this point. Can somebody help me? Thank you in advance.
P.S. I use number_field.
P.P.S.
In my controller:
def ccreate
#comment = Comment.new(params.permit(:rating, :body, :name, :game_id))
raise "It exploded into pieces!" unless #comment.save
end
In my view:
<% if #comments.count < 10 %>
<%= form_for(comment_path) do |f| %>
<div class="field">
<%= f.label :rating %><br>
<%= f.number_field :rating %>
</div>
<div class="field">
<%= f.label :body %><br>
<%= f.text_area :body %>
</div>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<% end %>
It's a strong params thing. Permit :comments, then the attributes
params.require(:comments).permit(:rating, :body, :name, :game_id)
and, use form_for #comment, not comment_path
I think you need to setup the form properly, I think the validation will work fine if the form posts as it should:
comments_controller.rb
def new
#comment = Comment.new
end
def create
#comment = Comment.new(comment_params)
raise "It exploded into pieces!" unless #comment.save
end
private
def comment_params
params.require(:comment).permit(:rating, :body, :name, :game_id)
end
There we are changing the strong params to require the new comment key in params (which will be the result of the second change to the view below). I also moved this into a private function to clean this up.
So then in your view:
<% if #comments.count < 10 %>
<%= form_for(#comment) do |f| %>
<div class="field">
<%= f.label :rating %><br>
<%= f.number_field :rating %>
</div>
<div class="field">
<%= f.label :body %><br>
<%= f.text_area :body %>
</div>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<% end %>
This uses the form_for tag with the model instance which should, I think, solve this issue.
try this in the comment_controller.rb
#rating = params[:comment][:rating].to_i
to make every input of the ratings to be converted as integer

undefined method `merge' for nil:NilClass in a form using text_field_tag

I'm following this tutorial to create tags for a model (in my case the model Post):
controllers/posts_controller.rb:
def create
#user = current_user
#post = #user.posts.new(params[:post])
if #post.save
redirect_to #post, notice: 'post was successfully created.'
else
render action: "new"
end
#post.tag!(params[:tags])
end
views/posts/_form.html.erb:
<%= form_for(#post) do |f| %>
<%= render 'shared/error_messages' %>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="field">
<%= f.label :tags %>
<%= f.text_field :tags, params[:tags] %>
</div>
<div class="actions">
<%= f.submit %>
</div>
views/posts/show.hmtl.erb:
<div class="tags">
<h4>Tags:</h4>
<%= render #post.tags %>
</div>
models/post.rb:
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags
def tag!(tags)
tags = tags.split(" ").map do |tag|
Tag.find_or_create_by_name(tag)
end
self.tags << tags
end
end
models/tag.rb:
class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts
end
db/migrate/(etc...)_create_tags.rb:
class CreateTags < ActiveRecord::Migration
def change
create_table :tags do |t|
t.string :name
end
create_table :tags_posts, :id => false do | t |
t.integer :tag_id, :post_id
end
end
end
Now, when I visit the posts form I get this error:
undefined method `merge' for nil:NilClass
Extracted source (around line #13):
10: </div>
11: <div class="field">
12: <%= f.label :tags %>
13: <%= f.text_field :tags, params[:tags] %>
14: </div>
15: <div class="actions">
16: <%= f.submit %>
When I visit a post I get this error:
SQLite3::SQLException: no such table: posts_tags: SELECT "tags".* FROM "tags" INNER JOIN "posts_tags" ON "tags"."id" = "posts_tags"."tag_id" WHERE "posts_tags"."post_id" = 7
Extracted source (around line #24):
21:
22: <div class="tags">
23: <h4>Tags:</h4>
24: <%= render #post.tags %>
25: </div>
26:
27: </div>
But I do have these tables as you can see in my schema.rb file:
create_table "tags", :force => true do |t|
t.string "name"
end
create_table "tags_posts", :id => false, :force => true do |t|
t.integer "tag_id"
t.integer "post_id"
end
Any suggestions to fix this?
Just in case anyone else comes across this old question through google:
You need to use 'value:' for the default value in a simple form.
<%= f.text_field :tags, value: params[:tags] %>
You have the table name backwards. HABTM looks for the models alphabetically. Look at the error carefully. It says posts_tags cannot be found. You create tags_posts. So change your table name to posts_tags.
try this <%= f.text_field_tag :tags, params[:tags] %> in your partial _form.html.erb.
<%= form_with(
url: order_register_path(session[:order_id]),
method: :put
) do |form| %>
<%= form.check_box :review_budget %>
<%= form.check_box :fast_delivery %>
<%= form.check_box :replace_similar %>
<div>
<%= f.submit "Continuar" %>
</div>
<% end %>
f.submit instead of that submit_tag

Nested form problem in Rails : NoMethodError in Show

I'm trying to build a simple product backlog application to teach myself Rails. For each product, there can be multiple product backlog entries, so I want to create a product view that shows the product information, all the backlog entries for the product, and includes a nested form for adding more backlog entries.
Everything works until I try to add the form to the view, which then results in the following error:
NoMethodError in Products#show
Showing app/views/products/show.html.erb where line #29 raised:
undefined method `pblog_ref' for #<Product:0x10423ba68>
Extracted source (around line #29):
26: <%= f.error_messages %>
27: <p>
28: <%= f.label :pblog_ref %><br />
29: <%= f.text_field :pblog_ref %>
30: </p>
31: <p>
32: <%= f.label :product %><br />
The product view where the problem is reported is as follows (the partial works fine, so I won't include that code):
<h1>Showing product</h1>
<p>
<b>Product ref:</b>
<%=h #product.product_ref %>
</p>
<p>
<b>Description:</b>
<%=h #product.description %>
</p>
<p>
<b>Owner:</b>
<%=h #product.owner %>
</p>
<p>
<b>Status:</b>
<%=h #product.status %>
</p>
<h2>Product backlog</h2>
<div id="product-backlog">
<%= render :partial => #product.product_backlogs %>
</div>
<% form_for(#product, ProductBacklog.new) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :pblog_ref %><br />
<%= f.text_field :pblog_ref %>
</p>
<p>
<%= f.label :product %><br />
<%= f.text_field :product %>
</p>
<p>
<%= f.label :description %><br />
<%= f.text_field :description %>
</p>
<p>
<%= f.label :owner %><br />
<%= f.text_field :owner %>
</p>
<p>
<%= f.label :status %><br />
<%= f.text_field :status %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
<%= link_to 'Edit', edit_product_path(#product) %> |
<%= link_to 'Back', products_path %>
This is the Product model:
class Product < ActiveRecord::Base
validates_presence_of :product_ref, :description, :owner
has_many :product_backlogs
end
This is the ProductBacklog model:
class ProductBacklog < ActiveRecord::Base
belongs_to :product
end
These are the routes:
map.resources :product_backlogs
map.resources :products, :has_many => :product_backlogs
All the columns exist in the schema for this model:
create_table "product_backlogs", :force => true do |t|
t.string "pblog_ref"
t.integer "product_id"
t.string "description"
t.string "owner"
t.string "status"
t.datetime "created_at"
t.datetime "updated_at"
end
I've checked what I'm doing against the Creating a weblog in 15 minutes with Rails 2 screencast, and in principle I seem to be doing the same thing as him - only his nested comments form works, and mine doesn't!
I hope someone can help with this, before I turn mad! I'm sure it's something trivial.
check your database, maybe some migration failed and you have only part of fields there
you can also check with running script/console first, and then issuing "p Product.new". It will show you an empty Product object with all known fields, like:
#./script/console
Loading development environment (Rails 2.3.5)
>> p User.new
#<User id: nil, type: nil, login: nil, name: "", email: nil, crypted_password: nil, salt: nil, created_by_id: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil, male: true, dept_id: nil, deleted: nil>
=> nil
It seems that you don't have pblog_ref field in your model. Take a look into migration that created products table, is there pblog_ref field?
EDIT:
Ok, it seems that this line is wrong:
<% form_for(#product, ProductBacklog.new) do |f| %>
It creates form for your #product not for ProductBacklog.new. Try:
<% form_for(ProductBacklog.new) do |f| %>
I always have problems with form_for arguments with some nested models, so I prefer using accepts_nested_attributes_for and then creating subobjects with fields_for.
In your case form_for should look like this:
<% form_for ProductBacklog.new, :url => new_product_product_backlog_path(#product) do |f| %>
However I didn't check it and it probably is wrong (as I said I always have problems with those paths).
The solution was to replace the line:
<% form_for(#product, ProductBacklog.new) do |f| %>
with:
<% form_for [#product, ProductBacklog.new] do |f| %>
Note the space after form_for, and the square brackets.

Resources