我正在尝试构建的功能允许用户访问餐厅。
我有用户,位置和餐馆模型。 地点有很多餐馆。
我创建了一个带有user_id和restaurant_id属性的Visits模型,以及一个带有create和destroy方法的visits_controller。
事实是,我无法创建实际的访问记录。有关如何实现这一目标的任何想法?或者我是以错误的方式去做的。
No route matches {:controller=>"restaurants", :location_id=>nil}
路线:
location_restaurant_visits POST /locations/:location_id/restaurants/:restaurant_id/visits(.:format) visits#create
location_restaurant_visit DELETE /locations/:location_id/restaurants/:restaurant_id/visits/:id(.:format) visits#destroy
型号:
class Visit < ActiveRecord::Base
attr_accessible :restaurant_id, :user_id
belongs_to :user
belongs_to :restaurant
end
查看:
<% @restaurants.each do |restaurant| %>
<%= link_to 'Visit', location_restaurant_visits_path(current_user.id, restaurant.id), method: :create %>
<% @visit = Visit.find_by_user_id_and_restaurant_id(current_user.id, restaurant.id) %>
<%= @visit != nil ? "true" : "false" %>
<% end %>
控制器:
class VisitsController < ApplicationController
before_filter :find_restaurant
before_filter :find_user
def create
@visit = Visit.create(params[:user_id => @user.id, :restaurant_id => @restaurant.id])
respond_to do |format|
if @visit.save
format.html { redirect_to location_restaurants_path(@location), notice: 'Visit created.' }
format.json { render json: @visit, status: :created, location: @visit }
else
format.html { render action: "new" }
format.json { render json: @visit.errors, status: :unprocessable_entity }
end
end
end
def destroy
@visit = Visit.find(params[:user_id => @user.id, :restaurant_id => @restaurant.id])
@restaurant.destroy
respond_to do |format|
format.html { redirect_to location_restaurants_path(@restaurant.location_id), notice: 'Unvisited.' }
format.json { head :no_content }
end
end
private
def find_restaurant
@restaurant = Restaurant.find(params[:restaurant_id])
end
def find_user
@user = current_user
end
end
答案 0 :(得分:1)
我在这看到很多问题。第一个是VisitController
的{{1}}操作中的这一行代码(以及create
操作中的相同行):
destroy
@visit = Visit.create(params[:user_id => @user.id, :restaurant_id => @restaurant.id])
是hash,所以你应该传递一个密钥(如果有的话),而不是一堆params
绑定。你的意思是:
key => value
请注意,您在过滤方法之前初始化@visit = Visit.create(:user_id => @user.id, :restaurant_id => @restaurant.id)
和@user
,因此您无需在此处访问@restaurant
。
但是,这行代码仍然有点奇怪,因为您正在创建一条记录,然后在几行之后保存它(params
)。这是多余的:if @visit.save
启动并保存记录,因此之后保存记录几乎毫无意义。您可能要做的是首先使用Visit.create
发起新的Visit
,然后保存:
Visit.new
我接下来要注意的是,您尚未在def create
@visit = Visit.new(:user_id => @user.id, :restaurant_id => @restaurant.id)
respond_to do |format|
if @visit.save
...
操作中启动@location
,但是您可以在此处引用它:
create
由于您需要每个餐馆路线的位置(因为format.html { redirect_to location_restaurants_path(@location), notice: 'Visit created.' }
是嵌套资源),您也可以为它创建一个方法和restaurant
,就像您使用{{1}一样}:
before_filter
下一个问题是,在您的观看中,find_restaurant
传递的是before_filter :find_location
...
def find_location
@location = Location.find(params[:location_id])
end
location_restaurant_path
和id
。这里有两个问题。首先,第一个参数应该是位置,而不是用户(匹配current_user
中的顺序)。下一个问题是,对于restaurant
方法,您必须传递实际对象,而不是对象的id。最后,您有location_restaurant_path
,但这里的_path
指的是HTTP方法,所以您想要的是method: :create
:
method
您需要在过滤前向method: :post
添加link_to 'Visit', location_restaurant_visits_path(@location, restaurant.id), method: :post
,以便在此处的视图中提供find_location
。
可能还有其他问题,但这些都是一些问题。
答案 1 :(得分:0)
location_id
是nil
,路径定义并没有说(/:location_id)
强制非零值以便路由到该路径;如果您可以从子项的属性派生它,则创建一个没有location_id
的新路由(即restaurant_id
引用已知道其自己的Restaurant
的{{1}}。