form_for 父模型 'show' 中的 "belongs_to" 模型
form_for a "belongs_to" model in 'show' of parent model
我有一个模型 "Breads" has_many "Posts"。
我想要一个表单来在 'show' 页面上为给定的 "Bread" 创建一个新的 "Post",它创建与 'Bread' 的记录的关联,其中 'show' 页面正在显示。
我尝试了几种不同的方法,但都出现错误。我在下面显示的方法给出了 "Association cannot be used in forms not associated with an object" 错误。
/views/breads/show.html.erb:
<p>
<strong>Bread Type:</strong>
<%= @bread.bread_type %>
</p>
<table>
<tr>
<th>Uploaded By</th>
<th>Comment</th>
<th>Picture</th>
</tr>
<% @bread.posts.each do |post| %>
<tr>
<td><%= post.uploader %></td>
<td><%= post.comment %></td>
<td><%= image_tag post.attachment_url.to_s %></td>
</tr>
<% end %>
</table>
<%= @bread.id %>
<%= simple_form_for @bread do |b| %>
<%= simple_fields_for :posts do |p| %>
<%= p.input :uploader %>
<%= p.input :comment %>
<%= p.association :bread, value: @bread.id %>
<%= p.file_field :attachment %><br>
<%= p.button :submit %>
<% end %>
<% end %>
<%= link_to 'Back', breads_path %>
config/routes.rb
Rails.application.routes.draw do
get 'welcome/index'
root 'welcome#index'
resources :breads
resources :posts
end
controllers/breads_controller.rb:
class BreadsController < ApplicationController
def index
@breads = Bread.all
end
def show
@bread = Bread.find(params[:id])
end
def new
@bread = Bread.new
end
def edit
@bread = Bread.find(params[:id])
end
def create
@bread = Bread.new(bread_params)
if @bread.save
redirect_to @bread
else
render 'new'
end
end
def update
@bread = Bread.find(params[:id])
if @bread.update(bread_params)
redirect_to @bread
else
render 'edit'
end
end
def destroy
@bread = Bread.find(params[:id])
@bread.destroy
redirect_to breads_path
end
private
def bread_params
params.require(:bread).permit(:bread_type)
end
end
models/bread.rb:
class Bread < ActiveRecord::Base
has_many :posts
validates :bread_type, presence: true, uniqueness: true
end
models/post.rb:
class Post < ActiveRecord::Base
belongs_to :bread
mount_uploader :attachment, AttachmentUploader
end
这样做 -
<%= simple_form_for @bread do |b| %>
<%= b.simple_fields_for(:posts,@bread.posts.build) do |p| %>
<%= p.input :uploader %>
<%= p.input :comment %>
<%= p.file_field :attachment %><br>
<%= p.button :submit %>
<% end %>
<% end %>
并在 beard_params
中进行更改
def beard_params
params.require(:bread).permit!
end
此处 permit!
需要所有参数,对于其他方式,您可以使用@pawan 的回答。
扩展@Amit Suroliya答案,您需要将posts_attributes
添加到bread_params
def bread_params
params.require(:bread).permit(:id, :bread_type, posts_attributes: [:id, :uploader, :comment, :bread_id, :attachment])
end
更新:
您还需要在面包模型中添加accepts_nested_attributes_for :posts
。
对不起,但这根本不是好方法,尽量不要滥用 rails 和休息路线 :)
这里是如何做到这一点的简单示例:
config/routes.rb
resources :bread do
resources :posts
end
这意味着会有如下路线:
bin/rake routes
breads - breads#index
bread/:id - breads#show
etc..
and most important
bread/:bread_id/posts/:id
...
这意味着帖子是面包的嵌套资源...
app/controllers/breads_controller.rb
controller BreadsController < BaseController
before_action :find_bread, except: %i(index create new)
.... action new, update, edit etc..
end
但现在它是 PostsController 中的重要部分..
app/controllers/posts_controller.rb
controller PostsController < BaseController
before_action :find_bread
before_action :find_post, except: %i(index new create)
before_action :build_post, only: %i(new create)
.... action new, update, edit etc..
# Example with :return link
def create
if @post.save
if params[:back] == 'bread_show'
redirect_to bread_path(@bread)
else
redirect_to bread_post_path(@bread, @post)
end
else
render 'new'
end
end
private
def build_post
if params[:post]
@post = @bread.posts.build(post_params)
else
@post = @bread.posts.build
end
end
def find_post
@post = @bread.posts.find(params[:id])
end
def find_bread
@bread = Bread.find(params[:bread_id])
end
... post params ...
end
现在你有完整的休息路线,你可以做你想做的事而不会那么痛苦和干净
... output hidden
<%= @bread.id %>
<%= simple_form_for @bread.posts.build do |b| %>
<%= p.input :uploader %>
<%= p.input :comment %>
<%= p.file_field :attachment %><br>
<%# Send back link to return on proper page %>
<%= p.hidden_field :back, 'bread_show' %>
<%= p.button :submit %>
<% end %>
<%= link_to 'Back', breads_path %>
可能会有一些错误,我凭记忆写这段代码,不能尝试:(
我有一个模型 "Breads" has_many "Posts"。 我想要一个表单来在 'show' 页面上为给定的 "Bread" 创建一个新的 "Post",它创建与 'Bread' 的记录的关联,其中 'show' 页面正在显示。
我尝试了几种不同的方法,但都出现错误。我在下面显示的方法给出了 "Association cannot be used in forms not associated with an object" 错误。
/views/breads/show.html.erb:
<p>
<strong>Bread Type:</strong>
<%= @bread.bread_type %>
</p>
<table>
<tr>
<th>Uploaded By</th>
<th>Comment</th>
<th>Picture</th>
</tr>
<% @bread.posts.each do |post| %>
<tr>
<td><%= post.uploader %></td>
<td><%= post.comment %></td>
<td><%= image_tag post.attachment_url.to_s %></td>
</tr>
<% end %>
</table>
<%= @bread.id %>
<%= simple_form_for @bread do |b| %>
<%= simple_fields_for :posts do |p| %>
<%= p.input :uploader %>
<%= p.input :comment %>
<%= p.association :bread, value: @bread.id %>
<%= p.file_field :attachment %><br>
<%= p.button :submit %>
<% end %>
<% end %>
<%= link_to 'Back', breads_path %>
config/routes.rb
Rails.application.routes.draw do
get 'welcome/index'
root 'welcome#index'
resources :breads
resources :posts
end
controllers/breads_controller.rb:
class BreadsController < ApplicationController
def index
@breads = Bread.all
end
def show
@bread = Bread.find(params[:id])
end
def new
@bread = Bread.new
end
def edit
@bread = Bread.find(params[:id])
end
def create
@bread = Bread.new(bread_params)
if @bread.save
redirect_to @bread
else
render 'new'
end
end
def update
@bread = Bread.find(params[:id])
if @bread.update(bread_params)
redirect_to @bread
else
render 'edit'
end
end
def destroy
@bread = Bread.find(params[:id])
@bread.destroy
redirect_to breads_path
end
private
def bread_params
params.require(:bread).permit(:bread_type)
end
end
models/bread.rb:
class Bread < ActiveRecord::Base
has_many :posts
validates :bread_type, presence: true, uniqueness: true
end
models/post.rb:
class Post < ActiveRecord::Base
belongs_to :bread
mount_uploader :attachment, AttachmentUploader
end
这样做 -
<%= simple_form_for @bread do |b| %>
<%= b.simple_fields_for(:posts,@bread.posts.build) do |p| %>
<%= p.input :uploader %>
<%= p.input :comment %>
<%= p.file_field :attachment %><br>
<%= p.button :submit %>
<% end %>
<% end %>
并在 beard_params
中进行更改 def beard_params
params.require(:bread).permit!
end
此处 permit!
需要所有参数,对于其他方式,您可以使用@pawan 的回答。
扩展@Amit Suroliya答案,您需要将posts_attributes
添加到bread_params
def bread_params
params.require(:bread).permit(:id, :bread_type, posts_attributes: [:id, :uploader, :comment, :bread_id, :attachment])
end
更新:
您还需要在面包模型中添加accepts_nested_attributes_for :posts
。
对不起,但这根本不是好方法,尽量不要滥用 rails 和休息路线 :)
这里是如何做到这一点的简单示例:
config/routes.rb
resources :bread do
resources :posts
end
这意味着会有如下路线:
bin/rake routes
breads - breads#index
bread/:id - breads#show
etc..
and most important
bread/:bread_id/posts/:id
...
这意味着帖子是面包的嵌套资源...
app/controllers/breads_controller.rb
controller BreadsController < BaseController
before_action :find_bread, except: %i(index create new)
.... action new, update, edit etc..
end
但现在它是 PostsController 中的重要部分..
app/controllers/posts_controller.rb
controller PostsController < BaseController
before_action :find_bread
before_action :find_post, except: %i(index new create)
before_action :build_post, only: %i(new create)
.... action new, update, edit etc..
# Example with :return link
def create
if @post.save
if params[:back] == 'bread_show'
redirect_to bread_path(@bread)
else
redirect_to bread_post_path(@bread, @post)
end
else
render 'new'
end
end
private
def build_post
if params[:post]
@post = @bread.posts.build(post_params)
else
@post = @bread.posts.build
end
end
def find_post
@post = @bread.posts.find(params[:id])
end
def find_bread
@bread = Bread.find(params[:bread_id])
end
... post params ...
end
现在你有完整的休息路线,你可以做你想做的事而不会那么痛苦和干净
... output hidden
<%= @bread.id %>
<%= simple_form_for @bread.posts.build do |b| %>
<%= p.input :uploader %>
<%= p.input :comment %>
<%= p.file_field :attachment %><br>
<%# Send back link to return on proper page %>
<%= p.hidden_field :back, 'bread_show' %>
<%= p.button :submit %>
<% end %>
<%= link_to 'Back', breads_path %>
可能会有一些错误,我凭记忆写这段代码,不能尝试:(