3

有几个位置,人们可以写关于这些位置的帖子。所以到目前为止我所做的是我创建了一个表 locations(rails generate scaffold locations name:string)和一个表 posts (rails generate scaffold posts title:string text:string author:string image:string location_id:integer)。所以 Tableposts有一个表的外键locations。因此可以在表格的显示操作中查看帖子。

/locations/1 的视图(显示位置模型的操作)和 /posts/new 的视图:

查看 /locations/1(显示位置模型的操作)在此处输入图像描述

我想要的是访问一个特定位置的人可以创建一个帖子,而无需填写 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

并且控制器中似乎没有错误了。现在NoMethodErrorhtml.erb-files中有一些:

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 %>

I already tried to simply delete the last code <%= link_to 'Back', posts_path %>and it still retrieves the error, even I saved everything, shut down the server and reopened it. But I think the problem is not the posts_path. Because if I change the <%= form_for @post do |f| %>in the html.erb file into <%= form_for @location.post do |f| %>, it retrieves a NoMethodError for 'post'

4

2 回答 2

3

It sounds like you want posts to be a nested resource under locations.

If that's what you're trying to do, then in config/routes.rb, you should have:

resources :locations do
  resources :posts
end

为 id = 1 的位置创建新帖子的 url 是/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

于 2012-06-13T19:30:32.270 回答
2

You could simply add a hidden field that contains the id of the location to the form where you are creating the post.

So, something like this:

<%= 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 %>

Where @location is an instance variable containing the current location that you're viewing.

于 2012-06-13T15:04:00.287 回答