0

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 请求。

在此处输入图像描述

4

2 回答 2

1

您需要attr_accessor :zombie_idtweet.rb.

并添加t.references :zombiecreate_tweets_migration

zombie_id应该是数据库中的列,而不是虚拟属性。

PS。accepts_nested_attributes_for :zombie也没有任何意义tweet.rb

于 2014-08-05T12:35:51.377 回答
0

换个试试

current_user.zombie.tweets.new(tweet_params)

在推文控制器的创建操作中:

current_user.zombie.tweets.build(tweet_params)

我认为保存推文时应该填充 id。

于 2014-08-05T12:33:06.583 回答