有几个地点,人们可以撰写有关这些地点的帖子。所以我到目前为止所做的是创建了一个表格位置(rails generate scaffold locations name:string)
和一个表格(rails generate scaffold posts title:string text:string author:string image:string location_id:integer)
。因此表posts
具有表locations
的外键。因此,可以在表格的show动作中查看帖子。
查看/ locations / 1(显示位置模型的操作)和查看/ posts / new:
我想要的是访问某个特定位置的人可以创建帖子而无需填写ID框,如下所示。它应该自动知道此帖子属于具有当前ID的位置。我需要在控制器中更改什么以及我在html.erb文件中需要做什么才能正常工作?我已经试过了......但是它检索了一个noMethod错误。
def newpost
@post = current_location.posts.build
respond_to do |format|
format.html
format.json { render json: @locations }
end
end
所以我遵循了Charles和Zajn的指示。
class PostsController < ApplicationController
(...)
def new
#@post = Post.new
@post = @location.posts.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: @post }
end
end
(...)
end
config/routes.rb
中的
resources :locations do
resources :posts
end
帖子部分
<%= form_for @post do |f| %>
<%= f.label :title, 'Title' %>
<%= f.text_field :title %>
<%= f.label :title, 'Text' %>
<%= f.text_field :text%>
<%= f.label :title, 'Author' %>
<%= f.text_field :author %>
<%= f.hidden_field :location_id %>
<%= f.submit "Submit" %>
<% end %>
并且似乎仍然存在错误:
NoMethodError in PostsController#new
详细信息:
undefined method `posts' for nil:NilClass
app/controllers/posts_controller.rb:28:in `new'
Request
Parameters:
{"location_id"=>"1"}
Response
Headers:
None
第二次尝试:现在我编辑了PostsController
def new
#@post = Post.new
@location = Location.find(params[:location_id]) # You can move this to a before_filter, if you prefer
@post = @location.posts.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: @post }
end
end
似乎控制器中没有错误了。现在NoMethodError
- 文件中有一些html.erb
:
undefined method 'posts_path' for #<#<Class:0x2404384>:0x204ed98>
1: <%= form_for @post do |f| %>
2: <%= f.label :title, 'Title' %>
3: <%= f.text_field :title %>
4:
app/views/posts/_form.html.erb:1:in `_app_views_posts__form_html_erb___1061496502_7409780'
app/views/posts/new.html.erb:3:in `_app_views_posts_new_html_erb__238125222_5750540'
app/controllers/posts_controller.rb:31:in `new'
我的_form.html.erb
:
<%= form_for @post do |f| %>
<%= f.label :title, 'Title' %>
<%= f.text_field :title %>
<%= f.label :title, 'Text' %>
<%= f.text_field :text%>
<%= f.label :title, 'Author' %>
<%= f.text_field :author %>
<%= f.hidden_field :location_id, :value => @location.id %>
<%= f.submit "Submit" %>
<% end %>
我的new.html.erb
<h1>New post</h1>
<%= render 'form' %>
<%= link_to 'Back', posts_path %>
我已经尝试简单地删除最后一个代码<%= link_to 'Back', posts_path %>
,它仍然检索错误,即使我保存了所有内容,关闭服务器并重新打开它。但我认为问题不在于posts_path。因为如果我将html.erb文件中的<%= form_for @post do |f| %>
更改为<%= form_for @location.post do |f| %>
,则会检索NoMethodError for 'post'
答案 0 :(得分:3)
听起来您希望帖子位于nested resource下的位置。
如果这是你要做的事情,那么在config/routes.rb
,你应该有:
resources :locations do
resources :posts
end
为id = 1的位置创建新帖子的网址为/locations/1/posts/new
,new
中的PostsController
操作应如下所示:
def new
@location = Location.find(params[:location_id]) # You can move this to a before_filter, if you prefer
@post = @location.posts.build
respond_to do |format|
format.html
format.json { render json: @post }
end
end
您的app/views/posts/_form.html.erb
部分内容应如下所示:
<%= form_for [@location, @post] do |f| %>
<%= f.label :title, 'Title' %>
<%= f.text_field :title %>
<%= f.label :title, 'Text' %>
<%= f.text_field :text%>
<%= f.label :title, 'Author' %>
<%= f.text_field :author %>
<%= f.hidden_field :location_id %>
<%= f.submit "Submit" %>
<% end %>
请注意,对于嵌套资源,您在视图中使用的路径助手是不同的。例如,要获取属于指定位置的帖子的index
操作的路径,您可以使用location_posts_path(@location)
,而不是posts_path
。
答案 1 :(得分:2)
您只需在创建帖子的表单中添加一个包含该位置ID的隐藏字段。
所以,像这样:
<%= form_for @post do |f| %>
<%= f.label :title, 'Title' %>
<%= f.text_field :title %>
<%= f.label :title, 'Text' %>
<%= f.text_field :text%>
<%= f.label :title, 'Author' %>
<%= f.text_field :author %>
<%= f.hidden_field :location_id, :value => @location.id %>
<%= f.submit "Submit" %>
<% end %>
其中@location
是包含您正在查看的当前位置的实例变量。