2012-12-01 90 views
3

我正在尝试构建的功能允许用户访问一家餐馆。从两个ID创建轨道记录

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

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

回答

1

我在这里看到了很多问题。第一个是你的VisitControllercreate行动这行代码(和相同的线在你的destroy行动):

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

paramshash,所以你应该传递一个键(如果有的话),不一堆key => value绑定。你大概的意思是:

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

请注意,您在之前过滤方法初始化@user@restaurant,这样你就不需要在这里访问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 
    ... 

我注意到接下来的事情是,你还没有开始在你的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_userrestaurantid。这里有两个问题。首先第一个参数应该是一个位置,而不是一个用户(匹配location_restaurant_path中的顺序)。接下来的问题是,对于_path方法,你必须传递实际的对象,而不是对象的ID。最后,你有method: :create,但这里的method指的是HTTP方法,所以你要的是method: :post

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

你必须过滤器之前添加find_locationRestaurantController,使在现有的@location在这里查看。

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

+0

完美的,特别要感谢澄清PARAMS/HASH位。 – mLuby

0

location_idnil并且路径定义不说(/:location_id)为了路由到那个路径而强制一个非零值;如果您可以从小孩的属性中派生它(即restaurant_id指已知道其自己的location_idRestaurant),则创建一条不含location_id的新路线。