3

我正在尝试构建的功能允许用户访问餐厅。

我有用户、位置和餐厅模型。地点有很多餐厅。

我创建了一个带有 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
4

2 回答 2

1

我在这里看到了很多问题。第一个是您的操作中的这行代码VisitControllercreate以及您的操作中的相同行destroy):

@visit = Visit.create(params[:user_id => @user.id, :restaurant_id => @restaurant.id])

params是一个hash,所以你应该给它一个键(如果有的话),而不是一堆key => value绑定。你的意思可能是:

@visit = Visit.create(:user_id => @user.id, :restaurant_id => @restaurant.id)

注意你初始化@user@restaurantin before filter方法,所以这里不需要访问params

不过,这行代码仍然有点奇怪,因为您正在创建一条记录,然后在几行之后保存它(if @visit.save)。这是多余Visit.create的:启动并保存记录,所以之后保存几乎没有意义。您可能想要做的是首先启动一个新VisitVisit.new,然后保存:

def create

  @visit = Visit.new(:user_id => @user.id, :restaurant_id => @restaurant.id)

  respond_to do |format|
    if @visit.save
    ...

我注意到的下一件事是您没有@location在您的create操作中启动 a,但是您在此处引用它:

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通过了idofcurrent_user和 of restaurant。这里有两个问题。首先,第一个参数应该是位置,而不是用户(匹配 中的顺序location_restaurant_path)。下一个问题是,对于_path方法,您必须传递实际对象,而不是对象的 id。最后,你有method: :create,但method这里指的是 HTTP 方法,所以你想要的是method: :post

link_to 'Visit', location_restaurant_visits_path(@location, restaurant.id), method: :post

您必须添加一个find_location前置过滤器才能RestaurantController@location此处的视图中使用。

可能还有其他问题,但这些都是开始的一些事情。

于 2012-12-01T05:14:00.473 回答
0

location_idnil并且路径定义没有说(/:location_id)强制在那里使用非零值以路由到该路径;location_id如果您可以从孩子的属性中派生它,则创建一条新路线(即 arestaurant_id指的是Restaurant已经知道自己的a location_id)。

于 2012-12-01T05:38:51.877 回答