通过id查找Ruby on Rails 4中的对象

5
我有以下 show-view,其中显示关于产品的基本信息并显示其他用户的产品。
<h1>Book <%= @product.name %></h1>
<% @products.each do |product| %>
<ul>
    <%= product.name %>
    <%= link_to "Make offer", {controller: "offers", :action => 'create', id: product.id }    %>
</ul>

控制器

def show
    @product = current_user.products.find(params[:id])
    @products = Product.all
end

我的目标是在两个产品之间进行报价。我创建了一个报价模型和相应的方法来制定报价:
class Offer < ActiveRecord::Base
  belongs_to :product

  belongs_to :exchanger, class_name: "Product", foreign_key: "exchanger_id" 

  validates :product_id, :exchanger_id, presence: true

  def self.request(product, exchanger)
    unless product == exchanger or Offer.exists?(product, exchanger)
    transaction do
      create(product: product, exchanger: exchanger, status: "oczekujace")
      create(product: exchanger, exchanger: product, status: "oferta")
    end
  end
  #other methods 
end

制作报价是有效的,因为我在控制台中进行了检查。 我的问题在于OffersController:
class OffersController < ApplicationController
 before_filter :setup_products

 def create
   Offer.request(@prod, @exchanger)
   redirect_to root_path
 end

 private

 def setup_products
   @prod = current_user.products.find(1)
   @exchanger = Product.find_by_id(params[:id])
 end
end

问题出在以下一行代码(使用商品id不为1的链接可以正常工作):
@prod = current_user.products.find(1)

但我不知道如何在数据库中找到与我的展示页面显示的实际产品相对应的对象,而不仅限于id = 1。

我猜您在此用户中没有产品ID为“1”的记录。错误信息:I guess you don't have record with product id 1 for this user. - RAJ
你是否拥有一个id为1的产品,且该产品属于当前用户? - Mandeep
使用上面显示的代码我没有问题。它可以工作。我有一个用户ID = 1。问题是,当我在我的展示页面上单击链接时,我的params [:id]设置为当前产品ID,这是可以的。setup_products中的第二行有效。问题在于第一行。我想获取实际产品对象,我的页面显示,并且我不知道如何做到这一点。我不知道如何在数据库中找到此对象。 - Przemek903
1个回答

9

我不知道如何在数据库中找到这个对象。

我不知道你问题的具体答案,但也许如果我解释一下你需要查看什么,你就可以找到解决方案:


查找

Rails并不是魔法-它使用ActiveRecord(一个ORM - 对象关系映射器),这意味着每当您发出查询(通过find)时,您的ORM(ActiveRecord)将为您搜索相关的数据库数据。

您所遇到的问题是,尽管您正在使用正确的语法进行查找,但您的数据库中可能没有id1的记录。

current_user.products.find(1)告诉ActiveRecord在当前用户及其产品范围内进行查询。因此,您将获得类似于以下内容:

SELECT * FROM 'products' WHERE user_id = '15' AND id = '1'


对象

此外,你必须记住 Ruby(以及构建在 Ruby 上的 Rails)是一种面向对象的语言。这意味着你在语言中加载/交互的所有内容都应该基于一个对象。

问题在于你没有正确地将你的对象关联到 Rails 框架上。我下面会描述我的意思,但本质上,如果你正确地构建了你的 Rails 框架,它将给你关联你的对象的能力,从而允许你从你的offer调用各种所需的products

当然,这只是一个简单的看法。你需要查看此图表以了解其工作原理:

enter image description here

简而言之,尝试将您的应用程序视为一系列对象,而不是逻辑流程。这将有助于您了解需要推动它前进的各种关联等内容。


资源

您提到在除了一个ID之外的展示页面上无法显示产品,我认为问题实际上是如何让您的“展示”操作正常工作。

如果是这种情况,让我来解释一下...

Rails是基于资源的(resource-based),这意味着您所做的一切/创建的一切都需要围绕某种资源(对象)展开。问题是,许多人不知道这一点,因此没有必要使他们的控制器结构复杂化:

enter image description here

上面是基于Rails的资源的典型“CRUD”路由结构。这应该演示了Rails通常构建的方式——围绕资源。

--

此外,Rails是建立在MVC编程模式上的 - 这意味着您需要使用控制器来填充一系列数据对象以供应用程序使用。

为此,如果您加载了一个资源,并希望用另一个对象的资源信息来填充它 - 您需要确保您已经设置了数据对象,以确保您可以正确地查找它们,这要么通过路由传递数据,要么使用持久性数据类型,如cookiessessions


您遇到的问题是需要将产品ID传递给您的控制器。我会按照以下方式进行操作(使用嵌套资源):
#config/routes.rb
resources :offers do
   resources :products #-> domain.com/offers/2/products
end

这将使您能够使用变量params[:id]加载产品控制器,以及params[:offer_id]用于提供的Offer,请注意保留HTML标签。
#app/controllers/products_controller.rb
Class ProductsController < ApplicationController
  def show
      @offer = Offer.find params[:offer_id]
      @product = Product.find params[:id]
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接