Rails 4:通过 form_for 创建新实例无效

Rails 4: new instance creation through form_for not working

这是关于 的后续问题。

在我们的Rails4 app中,有四种模式:

class User < ActiveRecord::Base
  has_many :administrations, dependent: :destroy
  has_many :calendars, through: :administrations
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

class Calendar < ActiveRecord::Base
  has_many :administrations, dependent: :destroy
  has_many :users, through: :administrations
end

class Post < ActiveRecord::Base
    belongs_to :calendar
end

以下是相应的迁移:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :first_name
      t.string :last_name
      t.string :email
      t.integer :total_calendar_count
      t.integer :owned_calendar_count

      t.timestamps null: false
    end
  end
end

class CreateAdministrations < ActiveRecord::Migration
  def change
    create_table :administrations do |t|
      t.references :user, index: true, foreign_key: true
      t.references :calendar, index: true, foreign_key: true
      t.string :role

      t.timestamps null: false
    end
  end
end

class CreateCalendars < ActiveRecord::Migration
  def change
    create_table :calendars do |t|
      t.string :name

      t.timestamps null: false
    end
  end
end

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
        t.references :calendar, index: true, foreign_key: true
        t.date :date
        t.time :time
        t.string :focus
        t.string :format
        t.string :blog_title
        t.text :long_copy
        t.text :short_copy
        t.string :link
        t.string :hashtag
        t.string :media
        t.float :promotion
        t.string :target
        t.integer :approval
        t.text :comment

      t.timestamps null: false
    end
  end
end

我们有以下表格来创建 posts:

<h2>Create a new post</h2>

<%= form_for(@post) do |f| %>

  <%= render 'shared/error_messages', object: f.object %>

    <tr>
        <%= f.hidden_field :calendar_id, value: @calendar.id %>
        <td class="field"><%= f.date_field :date, placeholder: "When do you want to publish this post?" %></td>
        <td class="field"><%= f.time_field :time, placeholder: "What time do you want to publish this post?" %></td>
        <td class="field"><%= f.text_field :focus, placeholder: "What is this post about?" %></td>
        <td class="field"><%= f.text_field :format, placeholder: "What type of post is this?" %></td>
        <td class="field"><%= f.text_field :blog_title, placeholder: "If this post is about a blog post, what is the title of the blog post?" %></td>
        <td class="field"><%= f.text_area :long_copy, placeholder: "What is the copy of the post?" %></td>
        <td class="field"><%= f.text_area :short_copy, placeholder: "What is the short copy of the post (to be used on Twitter for instance)?" %></td>
        <td class="field"><%= f.url_field :link, placeholder: "Which link to you want to embed in this post?" %></td>
        <td class="field"><%= f.text_field :hashtag, placeholder: "Which hashtag(s) do you want to you in this post?" %></td>
        <td class="field"><%= f.text_field :media, placeholder: "Which media file (image, video) do you want to include in this post?" %></td>
        <td class="field"><%= f.number_field :promotion, placeholder: "What advertising budget should be allocated to this post?" %></td>
        <td class="field"><%= f.text_field :target, placeholder: "Who do you want to target with this post?" %></td>
        <td class="field"><%= f.select(:approval, %w['Approved' 'Needs edits' 'To be deleted'], {prompt: 'How does this post look?'}) %></td>
        <td class="field"><%= f.text_area :comment, placeholder: "Any comment?" %></td>

        <td><%= f.submit "Create", class: "btn btn-primary" %></td>

    </tr>

<% end %>

此表单嵌入到 Calendars#Show 视图中,因此一旦创建了 post,它就会出现在相应的日历中。

这是我们的 PostsController:

class PostsController < ApplicationController

  def create
    @post = Post.create(post_params)
    if @post.save
      redirect_to root_url
    else
      render root_url
    end
  end

end

目前,无论何时我们提交表单,都没有任何反应:

编辑:这里是服务器日志:

Started GET "/calendars/1" for ::1 at 2015-07-07 22:21:07 -0700
Processing by CalendarsController#show as HTML
  Parameters: {"id"=>"1"}
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 1]]
  Post Exists (0.1ms)  SELECT  1 AS one FROM "posts" WHERE "posts"."calendar_id" = ? LIMIT 1  [["calendar_id", 1]]
  Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE "posts"."calendar_id" = ?  [["calendar_id", 1]]
  Rendered posts/_post.html.erb (0.7ms)
  Rendered shared/_error_messages.html.erb (0.0ms)
  Rendered shared/_post_form.html.erb (5.1ms)
  Rendered calendars/show.html.erb within layouts/application (13.7ms)
  Rendered layouts/_shim.html.erb (0.1ms)
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
  Rendered layouts/_header.html.erb (0.9ms)
  Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 145ms (Views: 144.0ms | ActiveRecord: 0.4ms)

编辑 2:这是新的服务器日志,在实施@miler350 在他的回答中推荐的内容后:

Started POST "/posts" for ::1 at 2015-07-08 09:09:58 -0700
Processing by PostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"+LS+B2/KiUq09cypZSQnzwj5xHbNnkYR6EC5hfjNCwc3/NfFkbWi3FJe0Zw3Mumsdnubnip5piQHXZ00eV1W2A==", "post"=>{"calendar_id"=>"", "date"=>"2015-08-20", "time"=>"12:04", "focus"=>"Test", "format"=>"Test", "blog_title"=>"Test", "long_copy"=>"Test", "short_copy"=>"Test", "link"=>"http://www.google.com", "hashtag"=>"Test", "media"=>"Test", "promotion"=>"50", "target"=>"Test", "approval"=>"'Approved'", "comment"=>"Test"}, "commit"=>"Create"}
Unpermitted parameter: calendar_id
   (0.1ms)  begin transaction
  SQL (0.7ms)  INSERT INTO "posts" ("date", "time", "focus", "format", "blog_title", "long_copy", "short_copy", "link", "hashtag", "media", "promotion", "target", "approval", "comment", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  [["date", "2015-08-20"], ["time", "2000-01-01 12:04:00.000000"], ["focus", "Test"], ["format", "Test"], ["blog_title", "Test"], ["long_copy", "Test"], ["short_copy", "Test"], ["link", "http://www.google.com"], ["hashtag", "Test"], ["media", "Test"], ["promotion", 50.0], ["target", "Test"], ["approval", 0], ["comment", "Test"], ["created_at", "2015-07-08 16:09:58.605712"], ["updated_at", "2015-07-08 16:09:58.605712"]]
   (0.6ms)  commit transaction
   (0.0ms)  begin transaction
   (0.0ms)  commit transaction
Redirected to http://localhost:3000/
Completed 302 Found in 9ms (ActiveRecord: 1.5ms)


Started GET "/" for ::1 at 2015-07-08 09:09:58 -0700
Processing by StaticPagesController#home as HTML
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
  Rendered static_pages/home.html.erb within layouts/static_pages (1.8ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  Rendered layouts/_static_header.html.erb (1.0ms)
  Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 148ms (Views: 147.5ms | ActiveRecord: 0.1ms)


Started GET "/users/1" for ::1 at 2015-07-08 09:10:02 -0700
Processing by UsersController#show as HTML
  Parameters: {"id"=>"1"}
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
  Rendered shared/_error_messages.html.erb (0.7ms)
  Rendered shared/_calendar_form.html.erb (5.0ms)
  Administration Exists (0.5ms)  SELECT  1 AS one FROM "administrations" WHERE "administrations"."user_id" = ? LIMIT 1  [["user_id", 1]]
  Administration Load (0.5ms)  SELECT "administrations".* FROM "administrations" WHERE "administrations"."user_id" = ?  [["user_id", 1]]
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 1]]
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 2]]
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 3]]
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 4]]
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 5]]
  Rendered administrations/_administration.html.erb (4.1ms)
  Rendered users/show.html.erb within layouts/application (32.1ms)
  Rendered layouts/_shim.html.erb (0.3ms)
  Rendered layouts/_header.html.erb (0.9ms)
  Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 150ms (Views: 135.3ms | ActiveRecord: 1.8ms)


Started GET "/calendars/1" for ::1 at 2015-07-08 09:10:04 -0700
Processing by CalendarsController#show as HTML
  Parameters: {"id"=>"1"}
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 1]]
  Post Exists (0.1ms)  SELECT  1 AS one FROM "posts" WHERE "posts"."calendar_id" = ? LIMIT 1  [["calendar_id", 1]]
  Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE "posts"."calendar_id" = ?  [["calendar_id", 1]]
  Rendered posts/_post.html.erb (1.1ms)
  Rendered shared/_error_messages.html.erb (0.0ms)
  Rendered shared/_post_form.html.erb (5.3ms)
  Rendered calendars/show.html.erb within layouts/application (13.9ms)
  Rendered layouts/_shim.html.erb (0.1ms)
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
  Rendered layouts/_header.html.erb (0.8ms)
  Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 113ms (Views: 111.2ms | ActiveRecord: 0.4ms)

编辑 3:这是我将 :calendar_id 添加到 PostsControllers 中允许的 post_params 时的服务器日志:

Started GET "/calendars/1" for ::1 at 2015-07-08 11:07:39 -0700
Processing by CalendarsController#show as HTML
  Parameters: {"id"=>"1"}
  Calendar Load (0.1ms)  SELECT  "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1  [["id", 1]]
  Post Exists (0.2ms)  SELECT  1 AS one FROM "posts" WHERE "posts"."calendar_id" = ? LIMIT 1  [["calendar_id", 1]]
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" WHERE "posts"."calendar_id" = ?  [["calendar_id", 1]]
  Rendered posts/_post.html.erb (0.7ms)
  Rendered shared/_error_messages.html.erb (0.0ms)
  Rendered shared/_post_form.html.erb (5.2ms)
  Rendered calendars/show.html.erb within layouts/application (17.9ms)
  Rendered layouts/_shim.html.erb (0.0ms)
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
  Rendered layouts/_header.html.erb (0.8ms)
  Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 160ms (Views: 147.4ms | ActiveRecord: 0.8ms)

问题可能来自哪里:模型、表单、控制器还是其他地方?

您必须创建 post 参数。

class PostsController < ApplicationController

  def create
    @post = Post.create(post_params)
    if @post.save
      redirect_to root_url
    else
      render root_url
    end
  end

  protected

  def post_params
    params.require(:post).permit(:date, :time, :focus....) #put all columns that you want to submit via form here. 
  end

end

您得到的很可能是验证错误,因为您可能需要为您的 post 提交至少一个字段。当 rails 没有收到时,你告诉它 render 而不是 redirect 所以你可能不会注意到重新加载。