1

我有模型帖子:

class Post < ActiveRecord::Base
has_one :location, :dependent => :destroy
belongs_to :person
belongs_to :activity

我有模型位置:

class Location < ActiveRecord::Base
belongs_to :post
validates :address, :presence => true
attr_accessible :address, :latitude, :longitude
geocoded_by :address
after_validation :geocode, :if => :address_changed?

我需要找到距离给定位置 50 英里的所有帖子。我找了一些例子,但没有找到我需要的东西。我试图以两种方式解决问题,但失败了。我是 Rails 的初学者,遇到的问题不计其数,我认为这对其他使用 has_one 模型的人很有用。

我试过:

post_controller.rb

def index
if params[:saddress].present?
  @locations = Location.near(params[:saddress], 50, :order => :distance)
  for location in @locations
    @posts << location.post
  end
else
  @posts = Post.all
end

index.html.erb

 <h1>Events</h1>
 <fieldset>
 <legend>Find event</legend>
 <%= form_tag(posts_path, :method => "get") do %>
   <%= label_tag(:saddress, "Address:") %>
   <%= text_field_tag :saddress, params[:saddress] %> <br/>
   <%= label_tag(:sactivity, "Activity type:") %>
   <%= select_tag :sactivity, options_from_collection_for_select(Activity.all, "id", "name", params[:sactivity]) %>
   <%= submit_tag "Поиск"%>
 <%end%>
 </fieldset>
 <%if @user%>
   <%= link_to "Новое событие", new_post_path %>
 <%end%>
 <table>
 <tr>
 <th>Created</th>
 <th>Author</th>    
 <th>Event</th>
 <th>Address</th>
 <th>Activity type</th>
 </tr>
 <% for post in @posts.sort.each %>
   <%if post%>
     <tr>
     <td><%= post.created_at %></td>
     <td><%= post.person.name %></td>
     <td><%= link_to post.name, post %></td>
     <td><%if post.location%><%= post.location.address %> <%end%></td>
     <td><%= post.activity.name %></td>
     </tr>
   <%end%>
 <%end%>
 </table>

它导致错误:

PostsController#index 中的 NoMethodError 出乎意料的是你有一个 nil 对象!您可能期望有一个 Array 的实例。评估 nil 时发生错误。<<

请帮助我有什么问题。也许还有其他一些简单的方法。

我也在posts_controller.rb中试过这个:

if params[:saddress].present?
  @locations = Location.near(params[:saddress], 50, :order => :distance)
  @posts = Post.find(:all, :include => [:location], :conditions => ["locations.id in ?", @locations])
else
  @posts = Post.all
end

在这种情况下,我遇到了 SQL 问题。

4

1 回答 1

0

在您的PostsController#index方法中,您需要初始化@posts变量。在您可以将项目附加到它之前成为一个数组。如果您省略了(就像您所做的那样),@posts 将被隐式初始化,nil从而解释您的错误。像这样更改您的代码:

def index
  if params[:saddress].present?
  @posts = []
    @locations = Location.near(params[:saddress], 50, :order => :distance)
    for location in @locations
      @posts << location.post
    end
  else
    @posts = Post.all
  end
end

上述代码的另一个(较短)变体是

def index
  if params[:saddress].present?
    @locations = Location.near(params[:saddress], 50, :order => :distance)
    @posts = @locations.collect(&:post)
    # ^^ this is the short form of the following equivalent expression:
    # @posts = @locations.collect{ |loc| loc.post }
  else
    @posts = Post.all
  end
end
于 2011-09-10T13:23:01.747 回答