Rails 新手,请原谅我一个简单的问题,但我很难过。
Rails 4.1.1 和 Ruby 2.1.2
我正在根据我从 Code School 关注的视频创建一个小型 Rails 应用程序(Zombie Twitter)。
我有四个控制器:Application、Welcome、Zombie 和 Tweets。
我有三个模型:用户、僵尸、推文。
has_one :zombie
用户(来自设计),。
僵尸,belongs_to :user
和 has_many :tweets
。
推文,belongs_to :zombie
。
注册用户时会创建一个新的僵尸记录。这行得通。
但是,在创建新推文时不会填充推文表中的zombie_id 字段。这是我无法弄清楚的,是我的问题。
另外:有人可以解释 build 和 build_model 方法以及何时使用它们吗?当我按照@zombie.tweets.build
. 是否有必要在 Rails 4.1.1 中调用这些方法,或者这是早期版本的 Rails 的保留?
用户.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :zombie
accepts_nested_attributes_for :zombie, allow_destroy: true
end
僵尸.rb
class Zombie < ActiveRecord::Base
belongs_to :user
has_many :tweets
validates_uniqueness_of :zombie_name
end
推文.rb
class Tweet < ActiveRecord::Base
belongs_to :zombie
attr_accessor :zombie_id
accepts_nested_attributes_for :zombie
end
应用控制器.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :set_zombie
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << [zombie_attributes: :zombie_name]
end
def set_zombie
if user_signed_in?
@zombie = Zombie.includes(:tweets).find_by user_id: current_user.id
end
end
end
TweetController.rb
class TweetsController < ApplicationController
before_action :set_tweet, only: [:show, :edit, :update, :destroy]
# GET /tweets/new
def new
@tweet = current_user.zombie.tweets.new
end
# POST /tweets
# POST /tweets.json
def create
@tweet = current_user.zombie.tweets.new(tweet_params)
logger.debug params
respond_to do |format|
if @tweet.save
format.html { redirect_to :root, notice: 'Tweet was successfully created.' }
format.json { render :show, status: :created, location: @tweet }
else
format.html { render :new }
format.json { render json: @tweet.errors, status: :unprocessable_entity }
end
end
end
def set_tweet
@tweet = Tweet.find(params[:id])
end
def tweet_params
params.require(:tweet).permit(:status, :is_public)
end
end
/tweets/_form.html.rb
<%= form_for([@zombie, @tweet]) do |f| %>
<% if @tweet.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@tweet.errors.count, "error") %> prohibited this tweet from being saved:</h2>
<ul>
<% @tweet.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label 'Public' %>
<%= f.check_box :is_public, checked: true %>
</div>
<div class="field">
<%= f.label :status %><br>
<%= f.text_area :status %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
create_zombies_migration
class CreateZombies < ActiveRecord::Migration
def change
create_table :zombies do |t|
t.string :zombie_name
t.timestamps
end
add_reference :zombies, :user, index: true
add_index :zombies, [:user_id, :id]
add_index :zombies, :zombie_name, unique: true
end
end
create_tweets_migration
class CreateTweets < ActiveRecord::Migration
def change
create_table :tweets do |t|
t.text :status, :limit => 140
t.boolean :is_public, default: true
t.timestamps
end
add_reference :tweets, :zombie, index: true
add_index :tweets, [:zombie_id, :id], unique: true
end
end
最后,这里是来自 development.log 的记录,详细说明了创建推文的 POST 请求。