【问题标题】:Create rails record from two ids从两个 id 创建 rails 记录
【发布时间】:2012-12-02 06:02:58
【问题描述】:

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

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

我创建了一个带有 user_id 和 restaurant_id 属性的 Visits 模型,以及一个带有 create 和 destroy 方法的 visit_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

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

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

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

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

    @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_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_location 到您的RestaurantController 以使@location 在此处的视图中可用。

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

    【讨论】:

    • 完美,特别感谢您澄清参数/哈希位。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-04
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 2012-12-22
      相关资源
      最近更新 更多