I've gone through Michael Hartl's RoR tutorial, and I'd like to expand the micropost model to allow a user to post an item that contains a keyword, price range, and condition field. I've replaced the "content" method in his tutorial with these new methods in the micropost form, micropost model, db migration, factories, and controller. However, when I try to load the form, I get the following error:
Showing C:/Sites/rails_projects/sample_app/app/views/shared/_micropost_form.html.erb where line #4 raised:
undefined method `keyword' for #<Micropost:0x54bd7e0>
Extracted source (around line #4):
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :keyword, placeholder: "iPhone 5 16gb" %>
</div>
<div class="field">
Trace of template inclusion: app/views/static_pages/home.html.erb
Rails.root: C:/Sites/rails_projects/sample_app
_micropost.html.erb code:
<li>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
data: { confirm: "You sure?" },
title: micropost.content %>
<% end %>
</li>
microposts_controller.rb code:
class MicropostsController < ApplicationController
before_action :signed_in_user
before_action :correct_user, only: :destroy
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to root_url
else
@feed_items = []
render 'static_pages/home'
end
end
def destroy
@micropost.destroy
redirect_to root_url
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
def correct_user
@micropost = current_user.microposts.find_by(id: params[:id])
redirect_to root_url if @micropost.nil?
end
end
factories.rb code:
FactoryGirl.define do
factory :user do
sequence(:name) { |n| "Person #{n}" }
sequence(:email) { |n| "person_#{n}@example.com"}
password "foobar"
password_confirmation "foobar"
factory :admin do
admin true
end
end
factory :micropost do
keyword "iPhone 5"
price "500"
condition "used"
user
end
end
[timestamp]_create_microposts.rb code:
class CreateMicroposts < ActiveRecord::Migration
def change
create_table :microposts do |t|
t.string :keyword
t.integer :price
t.string :condition
t.integer :user_id
t.timestamps
end
add_index :microposts, [:user_id, :created_at]
end
end
micropost.rb code:
class Micropost < ActiveRecord::Base
belongs_to :user
default_scope -> { order('created_at DESC') }
validates :keyword, presence: true, length: { maximum: 140 }
validates :price, presence: true, length: { maximum: 140 }
validates :condition, presence: true, length: { maximum: 140 }
validates :user_id, presence: true
end
_micropost_form.html.erb code:
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :keyword, placeholder: "iPhone 5 16gb" %>
</div>
<div class="field">
<%= f.text_area :price, placeholder: "$350-400" %>
</div>
<div class="field">
<%= f.text_area :condition, placeholder: "Used" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
How can I correctly define these new methods, and make it so that the three attributes are saved in the db under one post every time they're submitted?
尝试运行迁移(如果尚未运行),然后重新启动服务器
http://sourceforge.net/projects/sqlitebrowser/
download that, run that application. open your db... it'll be wherever your app is... then db/development.sqlite3
click on the browse data
tab. switch to your microposts. are your new columns in there? probably not...
my guess is you just went into your migration files and started tinkering. no no.
once you run a db:migrate, your database is built. any changes that you want to make have to be added in the form of a new migration or rollback.
so in your case... you'll probably want to to run rails g migration add_price_to_microposts
, which will create a new file under db/migrate.
class AddPriceToMicroposts < ActiveRecord::Migration
def change
add_column :microposts, :keyword, :string
add_column :microposts, :price, :integer
add_column :microposts, :condition, :string
end
end
your other option is to rollback. rake db:migrate:down VERSION=20131130180735
. this will kill your table... but that's probably ok in your case. now you can go back into that migration file... make the changes that you want in the form of t.sting :whatever
, then when you're content, rake db:migrate
to rebuild the table.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.