【问题标题】:Rails 2 way association not functioningRails 2 方式关联不起作用
【发布时间】:2014-01-26 08:02:53
【问题描述】:

我有一点问题。我一直在开发 Rails 应用程序并遇到了一个我无法解决的问题。

到目前为止,我的应用程序允许用户将产品详细信息输入数据库(存储在“产品表”中)这是我正在使用的数据库的架构。

ActiveRecord::Schema.define(version: 20140126073333) do

  create_table "ijns", force: true do |t|
    t.integer  "number"
    t.integer  "product_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "quantity"
  end

  add_index "ijns", ["number"], name: "index_ijns_on_number"

  create_table "products", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "ijn_id"
  end

  add_index "products", ["name"], name: "index_products_on_name"

end

还有一个名为“ijns”的表,它为每个产品分配一个唯一标识符。这个 ijn 没有被故意设为主键,因为我不希望它成为自动递增的值。

B/w IJN 和 Product 的关系是:

一个产品 has_many ijns 和 一个 ijn 属于一个产品。

这是我的产品模型

class Product < ActiveRecord::Base
  has_many :ijns
  validates :name, presence: true, length: { minimum: 10 }, uniqueness: true
end

IJN 模型。

class Ijn < ActiveRecord::Base
  belongs_to :product

  validates :number, presence: true, uniqueness: true, length: { is: 4 }, numericality: {   only_integer: true }
  validates :product_id, presence: true
  validates :quantity, presence: true
end

我能够从 IJN 方面获得关联,即,我能够通过使用以下方式访问产品模型的字段:

@ijn.product.name

但我无法从产品型号访问“ijns”表的“编号”字段

我希望我已经清楚地解释了我的问题。如果需要其他信息,请告诉我。急切地等待一些答复! :)

第一次编辑:

当我在 sqlite3 数据库浏览器中查看我的“产品”表时,ijn_id 列存在,但由于某种原因没有条目。这是截图:

【问题讨论】:

  • 你试过什么?如果你写@product.ijns,你会得到什么? NoMethodError 还是别的什么?
  • 是的罗宾,我得到一个 NoMethodError

标签: ruby-on-rails ruby model-associations


【解决方案1】:

问题是你定义了一个Producthas_many:ijns。这与架构中具有 ijn_id 的产品冲突。

因此,当您尝试执行 product.ijn 时,您会收到错误。

编辑:

如果一个产品真的有很多 ijns,那么ijn_id 对 ActiveRecord 和数据库没有意义。他们不知道应该指哪个 ijn。我怀疑您希望它引用分配给产品的最后一个 ijn。

在这种情况下,一种解决方案是将属性更改为current_ijn_id 之类的东西。每次需要更新时,您都必须手动分配一个值。

您也可以使用product.ijns.last。问题是您需要确保 .last 每次都会为您提供正确的 ijn。例如,如果由于某种原因您将产品“回滚”到旧的 ijn,它可能不起作用。

【讨论】:

  • 是的,我就是这么想的。我尝试做product.ijn_id ..这也不起作用..好吧..你建议我做什么来解决这个问题?我需要两种方式访问​​表格.. ijn.product.name 正在工作.. 我需要'product.ijn.number'..
  • 使关联保持一致。那么Product 是否有一个或多个Ijns?如果有,请将has_many 更改为has_one。 ActiveRecord 关联基础:guides.rubyonrails.org/association_basics.html
  • 好的,让我在这里澄清一下。产品模型的一个实例只能有一个 IJN,而 IJN 模型的一个实例只能有一个产品。但是,同样的产品也可以在应用程序的生命周期内分配另一个 IJN。这不是说一个产品有_many IJN 吗?
  • 当产品被分配一个新的ijn时会发生什么,旧的会被丢弃吗?如果是这样,has_one 是合适的。如果没有,即产品会随着时间的推移累积 ijns,请使用 has_many
  • 正是.. 后者.. 随着时间的推移,产品会累积 IJN。这就是我使用 has_many 关联的原因。就像我说的,它从 IJN 方面工作,即 ijn.product.name 返回与 IJN 关联的产品的名称,但 product.ijn.number 只返回 NoMethodError 之外的任何内容。此外,ijn_id 不会在 products 表中更新,如上所示..
【解决方案2】:

似乎你让这比你需要的更复杂:


表格

您的ijn 号码就像SKU(您系统的唯一标识符)对吗?既然是产品的属性,为什么不直接放在产品表中:

 #products table
 id | ijn | name | created_at | updated_at

这立即否定了对额外表的要求(也节省了查询)


额外

如果您想为您的product 调用额外的数据,您需要一个专门用于该数据的表

对我来说,model 是具有特定目的的数据集合。拥有ijn 的模型并不构成这一点

#app/models/products.rb
Class Product < ActiveRecord::Base
    has_one :profile, class_name: "ProductProfile"
end

#app/models/product_profile.rb
Class ProductProfile < ActiveRecord::Base
    belongs_to :product
end

这将允许您调用类似@product.profile.quantity 或类似的名称

【讨论】:

  • 是的,我也这么认为..这就是为什么当我决定我的数据库应该采用的结构时,我决定将我的产品放在一个单独的表中,因为它允许在这种情况下扩展我的应用程序我需要为我的产品模型添加更多属性......这基本上是我使用 2 个单独的表的原因。此外,由于产品会在应用程序生命周期中不断分配给 IJN 的新独特值,因此最好将其放在自己的表中。
【解决方案3】:
puts Product.first.ijn.number

这应该根据你想要做的工作。

【讨论】:

  • 嘿@murrekatt,我试过了,但我又得到了:“NoMethodError: undefined method `ijn' for #<0x007ff76b065378>
【解决方案4】:

非常感谢您的帮助...我做了更多阅读并找到了我的解决方案。对于像我这样的一对多关系,您只需要在一侧提供引用表的“id”,即,包括“ijn”表中的“product_id”列。我删除了“products”表中的“ijn_id”列,并在“ProductsController”中包含了一行代码。这里是:

...
def show
    @product = Product.find(params[:id])
    #getting the related IJN
    @ijn = Ijn.find(:all, :conditions => ['product_id = ?',@product])
end

...

现在,在视图中,可以简单地引用关联的产品名称

<% @ijn.map do |i| %>
    <tr>
      <td><%=i.number %></td>
      <td><%= i.quantity %></td>
      <td><%= i.name %></td> #this returs the assocaiated product name
      <td><%= Date::MONTHNAMES[i.product.created_at.month] %></td>
      <td>placeholder</td>
      <td>placeholder</td>
    </tr>
<% end %>

返回产品名称和相关 IJN 的列表。我没有在上面的代码中添加任何样式。

我希望这对面临类似问题的其他人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多