Rails 4: 新实例创建并保存到数据库但未显示在视图中
Rails 4: new instance is created and saved to database but not displayed in view
在我们的Rails 4 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>
<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,它就会出现在相应的日历中。
编辑 2:这是你 PostsController
:
class PostsController < ApplicationController
def create
@post = Post.create!
if @post.save
redirect_to root_url
else
render root_url
end
end
end
目前,每当我们提交表单时,实际上都会创建一个 post(我们通过控制台检查过)。
编辑:实际上,创建了新的@post并将其保存到数据库中,但所有值都设置为nil
。看来我们在将数据从表单保存到数据库时也遇到了问题。
然而,它并没有出现在相应的日历中。
我们认为这是因为创建 post 时,未将活动日历(嵌入表单的日历)的 calendar_id 添加到新的 post 实例。
但是,我们不知道如何实现它:
- 我们是否应该创建一个
active_calendar
方法,然后使用它自动将活动日历的 active_calendar
id
分配给新创建的 @post
?
- 我们是否应该简单地将活动日历
id
声明为变量,在 post 控制器或 post 模型中,以便我们可以在新的 @post
已创建?
- 我们是否应该通过表单中的隐藏字段将活动日历
id
包含在新创建的 @post
中?
我们有点碰壁了,不确定我们做错了什么。
知道如何解决这个问题吗?
更新:正如@Fire-Dragon-DoL 在其回答的评论中所建议的,我们将使用隐藏字段。
下面的代码行得通吗?
<td type="hidden" value="#{@calendar.id}"><% f.number_field :calendar_id %></td>
您可能希望嵌套路由,例如:
resources :calendars do
resources :posts
end
现在更改您的表单以包含您希望与 post 相关联的日历,例如:
form_for([@calendar, @post])...
然后在您的 posts 控制器创建路径中,您可以找到您的日历并使用类似以下内容构建您的 post:
def create
my_calendar = Calendar.find(params[:calendar_id])
post = my_calendar.posts.create(post_params)
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:date, :time, :focus, :format, :blog_title, :long_copy, :short_copy, :link, :hashtag, :media, :promotion, :target, :approval, :comment)
end
我不确定您的 "active calendar" 信息是如何或存储在哪里的,您肯定需要它。将其作为 User
的字段,这是一个不错的选择。
然后我会创建一个应用程序控制器方法,例如
def active_calendar
# Assuming you have a method to return current logged in user
current_user.try(:active_calendar)
end
然后在创建时post你可以很容易地执行以下操作
attrs = post_params.merge(calendar: active_calendar)
@post = Post.new(attrs)
# Or whatever logic you want
@post.save
仅当允许用户指定与活动日历不同的日历时才使用隐藏字段,否则它可能只是一个安全漏洞
注意我写的代码也是nil-proof
在我们的Rails 4 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>
<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,它就会出现在相应的日历中。
编辑 2:这是你 PostsController
:
class PostsController < ApplicationController
def create
@post = Post.create!
if @post.save
redirect_to root_url
else
render root_url
end
end
end
目前,每当我们提交表单时,实际上都会创建一个 post(我们通过控制台检查过)。
编辑:实际上,创建了新的@post并将其保存到数据库中,但所有值都设置为nil
。看来我们在将数据从表单保存到数据库时也遇到了问题。
然而,它并没有出现在相应的日历中。
我们认为这是因为创建 post 时,未将活动日历(嵌入表单的日历)的 calendar_id 添加到新的 post 实例。
但是,我们不知道如何实现它:
- 我们是否应该创建一个
active_calendar
方法,然后使用它自动将活动日历的active_calendar
id
分配给新创建的@post
? - 我们是否应该简单地将活动日历
id
声明为变量,在 post 控制器或 post 模型中,以便我们可以在新的@post
已创建? - 我们是否应该通过表单中的隐藏字段将活动日历
id
包含在新创建的@post
中?
我们有点碰壁了,不确定我们做错了什么。
知道如何解决这个问题吗?
更新:正如@Fire-Dragon-DoL 在其回答的评论中所建议的,我们将使用隐藏字段。
下面的代码行得通吗?
<td type="hidden" value="#{@calendar.id}"><% f.number_field :calendar_id %></td>
您可能希望嵌套路由,例如:
resources :calendars do
resources :posts
end
现在更改您的表单以包含您希望与 post 相关联的日历,例如:
form_for([@calendar, @post])...
然后在您的 posts 控制器创建路径中,您可以找到您的日历并使用类似以下内容构建您的 post:
def create
my_calendar = Calendar.find(params[:calendar_id])
post = my_calendar.posts.create(post_params)
redirect_to root_path
end
private
def post_params
params.require(:post).permit(:date, :time, :focus, :format, :blog_title, :long_copy, :short_copy, :link, :hashtag, :media, :promotion, :target, :approval, :comment)
end
我不确定您的 "active calendar" 信息是如何或存储在哪里的,您肯定需要它。将其作为 User
的字段,这是一个不错的选择。
然后我会创建一个应用程序控制器方法,例如
def active_calendar
# Assuming you have a method to return current logged in user
current_user.try(:active_calendar)
end
然后在创建时post你可以很容易地执行以下操作
attrs = post_params.merge(calendar: active_calendar)
@post = Post.new(attrs)
# Or whatever logic you want
@post.save
仅当允许用户指定与活动日历不同的日历时才使用隐藏字段,否则它可能只是一个安全漏洞
注意我写的代码也是nil-proof