我有模特Post:
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模型很有用。
我试过了:
posts_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 当你没想到它时,你有一个零对象! 您可能期望一个Array实例。 在评估nil时发生错误。&lt;&lt;
请帮我解决错误。也许还有其他一些简单的方法。
我也在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问题。
答案 0 :(得分:0)
在PostsController#index
方法中,您需要初始化@posts
变量。在您可以向其追加项目之前成为一个数组。如果你省略(像你一样),@ post将被隐式初始化为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