我正在尝试构建的功能允许用户访问餐厅。
我有用户、位置和餐厅模型。 地点有很多餐馆。
我创建了一个带有 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 %>
Controller :
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
最佳答案
我在这里看到了很多问题。首先是 VisitController
的 create
操作中的这行代码(以及 destroy
操作中的同一行):
@visit = Visit.create(params[:user_id => @user.id, :restaurant_id => @restaurant.id])
params
是一个 hash ,所以你应该传递给它一个键(如果有的话),而不是一堆 key => value
绑定(bind)。你的意思可能是:
@visit = Visit.create(:user_id => @user.id, :restaurant_id => @restaurant.id)
请注意,您在过滤器方法之前初始化了 @user
和 @restaurant
,因此您不需要在此处访问 params
。
不过,这行代码仍然有点奇怪,因为您正在创建一条记录,然后几行之后您正在保存它 (if @visit.save
)。这是多余的:Visit.create
启动并保存记录,因此之后保存几乎没有意义。您可能想要做的是首先使用 Visit.new
启动一个新的 Visit
,然后保存它:
def create
@visit = Visit.new(:user_id => @user.id, :restaurant_id => @restaurant.id)
respond_to do |format|
if @visit.save
...
我注意到的下一件事是您没有在 create
操作中启动 @location
,但您随后在此处引用了它:
format.html { redirect_to location_restaurants_path(@location), notice: 'Visit created.' }
由于您将需要每条餐厅路线的位置(因为 restaurant
是一个嵌套资源),您不妨为它创建一个方法和 before_filter
,就像您一样有 find_restaurant
:
before_filter :find_location
...
def find_location
@location = Location.find(params[:location_id])
end
下一个问题是,在您看来,您的 location_restaurant_path
已通过 current_user
和 restaurant
的 id
.这里有两个问题。首先,第一个参数应该是位置,而不是用户(匹配 location_restaurant_path
中的顺序)。下一个问题是对于 _path
方法,您必须传递实际对象,而不是对象的 id。最后,你有了method::create
,但是这里的method
指的是HTTP方法,所以你想要的是method::post
:
link_to 'Visit', location_restaurant_visits_path(@location, restaurant.id), method: :post
您必须在 RestaurantController
过滤器之前添加一个 find_location
以使此处的 View 中可以使用 @location
。
可能还有其他问题,但这些是开始的一些事情。
关于ruby-on-rails - 从两个 id 创建 rails 记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13656521/