I created a basic scaffold for a Foo model with a single property - bar:String
foos/new.html.erb:
<h1>New foo</h1>
<% form_for(#foo) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :bar %><br />
<%= f.text_field :bar %>
</p>
<p>
<%= f.submit 'Create' %>
</p>
<% end %>
<%= link_to 'Back', foos_path %>
But I get a NoMethodError for my 'bar' property:
NoMethodError in Foos#new
Showing app/views/foos/new.html.erb where line #8 raised:
undefined method `bar' for #<Foo id: nil, created_at: nil, updated_at: nil>
Extracted source (around line #8):
5:
6: <p>
7: <%= f.label :bar %><br />
8: <%= f.text_field :bar %>
9: </p>
10: <p>
11: <%= f.submit 'Create' %>
As you can see, bar the only property in my Foo model:
class CreateFoos < ActiveRecord::Migration
def self.up
create_table :foos do |t|
t.String :bar
t.timestamps
end
end
def self.down
drop_table :foos
end
end
And the new method in the foos_controller is from the default scaffold:
def new
#foo = Foo.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #foo }
end
end
Any ideas would be appreciated
It would seem you capitalized the word String in your db migration. Try it with a lower case s and force the migration to run again (rake db:migrate:redo, assuming that this was your latest migration, otherwise use
rake db:migrate:down VERSION=29843923 && rake db:migrate:up VERSION=29843923
where 29843923 is your migration timestamp.).
Did you executed your migration?
Related
I have been following both the old and revised railscasts & this for something that i have to make along the same lines
I followed it upto some point but neither are the questions being displayed on the form nor are the answers getting added . Following is my model code
answers.rb
class Answer < ActiveRecord::Base
attr_accessor :content, :question_id
belongs_to :question
end
surveys.rb
class Survey < ApplicationRecord
attr_accessor :name, :questions_attributes
has_many :questions
accepts_nested_attributes_for :questions, allow_destroy: true
end
questions.rb
class Question < ApplicationRecord
attr_accessor :content, :survey_id, :answers_attributes
belongs_to :survey
has_many :answers
accepts_nested_attributes_for :answers, allow_destroy: true
end
Surveys Controller
class SurveysController < ApplicationController
before_action :set_survey, only: [:show, :edit, :update, :destroy]
# GET /surveys
# GET /surveys.json
def index
#surveys = Survey.all
end
# GET /surveys/1
# GET /surveys/1.json
def show
end
# GET /surveys/new
def new
#survey = Survey.new
3.times do
question = #survey.questions.build
4.times { question.answers.build }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_survey
#survey = Survey.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def survey_params
params.require(:survey).permit(:name, :question_id)
end
end
Views
_form.html.erb
<%= f.fields_for :questions do |builder| %>
<%= render 'question_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Question", f, :questions %>
_question_fields.html.erb
<fieldset>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question" %>
<%= f.fields_for :answers do |builder| %>
<%= render 'answer_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Add Answer", f, :answers %>
</fieldset>
_answers_fields.html.erb
<p>
<%= f.label :content, "Answer" %>
<%= f.text_field :content %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove" %>
</p>
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #survey.name %>
</p>
<ol>
<% for question in #survey.questions %>
<li><%= h question.content %></li>
<% end %>
</ol>
<p>
<%= link_to "Edit", edit_survey_path(#survey) %> |
<%= link_to "Destroy", #survey, :confirm => 'Are you sure?', :method => :delete %> |
<%= link_to "View All", surveys_path %>
</p>
Migrations
class CreateSurveys < ActiveRecord::Migration[5.0]
def change
create_table :surveys do |t|
t.string :name
t.timestamps
end
end
end
class CreateQuestions < ActiveRecord::Migration[5.0]
def change
create_table :questions do |t|
t.string :survey_id
t.string :integer
t.text :content
t.timestamps
end
end
end
Is there anything else i am missing out that needs to be done in rails 5 , i have been hours at this and it still confuses me why does it show me this error - Table 'app.answers' doesn't exist when i am calling answers from nested form . Any help in this regard would be very much appreciated .
The main issue here is it looks like you forgot an 'answer' migration to create the tables, create that and run it and should fix things up.
Additionally, those attr_accessor calls are going to be messing things up. They were required in older versions of Rails, but aren't anymore and now just serve throw things off. Example
With attr_accessor code
post = Post.new(title: "Something")
#=> #<Post id: nil, title: nil, created_at: nil, updated_at: nil>
post.title = "Something"
#=> "Something"
puts post
#=> #<Post id: nil, title: nil, created_at: nil, updated_at: nil>
Without
post = Post.new(title: "Something")
#=> #<Post id: nil, title: "Something", created_at: nil, updated_at: nil>
post.title = "Something Else"
#=> "Something Else"
puts post
#=> #<Post id: nil, title: "Something Else", created_at: nil, updated_at: nil>
As you can see, the first block, where my Post model had the attr_accessor for the title attribute, nothing was working as expected; I couldn't update the title. Once I removed it, things started to work as they should.
Based on the chat discussion, your _form.html.erb is missing form_for tag, and should looks something like
<%= form_for #survey do |f| %>
<%= f.label :name %><br />
<%= f.text_field :name %>
<!-- your current code here -->
<% end %>
you've got _answers_field.html.erb and in _question_fields.html.erb are calling
<%= render 'answer_fields', f: builder %>
Notice, the plural/singular mismatch.
and lastly, in your controller, you aren't permitting the nested attribute params which should end up looking like (unless I'm mistaken)
def survey_params
params.require(:survey).permit(:name, :question_attributes: [:id, :content, :_destroy, answer_attributes: [:id, :content, :_destroy])
end
Last couple of issues from chat were that the associations needed inverse_of because belongs_to is required by default in rails 5. And the last minor thing is that Answer is currently inheriting ActiveRecord::Base and the other models ApplicationRecord
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.
I'm learning Rails and I am working on a blog. I'm facing the problem that one of the fields of the form is not mapping to the database. When I save a new article the name maps to the db but not story. I end Up having a null column in the db.
My migration
class CreateArticles < ActiveRecord::Migration
def change
create_table :articles do |t|
t.string :name
t.text :story
t.timestamps
end
end
end
forms/new.html.erb
<h1>New Article</h1>
<%= form_for :article, url: articles_path do |f| %>
<p>
<%= f.label :name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :story %><br>
<%= f.text_area :story %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
controller
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(:name, :story)
end
end
Uses debugger gem and check the params are passes correct it will be good if you can just share the devlopment.log
When I try to access the view, an error is returned:
undefined method 'title' for #Task id: nil, created_at: nil, updated_at: nil
tasks_controller.rb (Controller)
class TasksController < ApplicationController
def new
#task = Task.new
end
def create
#task = Task.new(params[:task])
if #task.save
redirect_to new_task_path
end
end
end
/tasks/new.html.erb (View)
<%= form_for :task, url: tasks_path do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :details %><br>
<%= f.text_area :details %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
task.rb (Model)
class Task < ActiveRecord::Base
belongs_to :user
attr_accessible :title, :details, :user_id, :volunteers
end
What should I do?
You have not defined fields in your database, see:
#Task id: nil, created_at: nil, updated_at: nil
There is no title nor details there, do this:
rails g migration add_title_and_details_to_tasks title details
Check that your migration file is correctly creating these 2 fields.
Then run rake db:migrate. Next time remember to generate your resource with these fields:
rails g scaffold Task title details
This way, when you migrate your fields will be there.
It looks like you have pending migration(s) (do you have title in your schema.rb).
other note: build your form for #task
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