English 中文(简体)
铁路复杂关系的建模
原标题:Modeling Complex Relationships in Rails
  • 时间:2009-09-18 11:19:14
  •  标签:

UPDATE

OK, I figured it out. I had to call the following for varieties:
<%=h @user.varieties.find_by_product_id(product.id).name %>

我在此提出以下两个问题:

(1) 在编辑/删除记录时,这是否会造成问题,因为我不说加入模式? 我看到了一些Ryan Bates录像带,他在那里强调了这一点,但我很难在此提及加入模式。 换言之,上述代码是否应当通过<编码>用户_products加以使用?

如果我使用参考表格的以下代码,Im只能显示variety_id。 表格中(因为表格中没有物种名称栏)。 我不敢确定如何在表格中参考variety_id,但随后去各表,从“姓名”栏中获取各种语文的实际名称。

<% @user.products.each do |product| %>
   <% @user.user_products.find_by_product_id(product.id).variety_id %>
<% end %> 

(2) 这一复杂情况是否适当放在了眼层,还是有更好的办法将其移至模型或控制器?

感谢。

Original question below is now solved ...

I have the following models:
- users
- products
- varieties - user_products

这里是我试图做的真正的世界版本。 让我们说,用户是一种杂货店。 产品是水果,就像les。 杂草种类,如fu和 m。

我需要做以下事情:

  • 用户可以在网页上添加许多类型的产品。 这些产品可以包括多种品种,但用户是需要列入任何品种的NOT。 例如,Popps Grocery仓库可以在其网页上添加 app。 如果他们想要显示这一点,那就应该ok。 然而,它们还可以增加细节,包括它们所携带的 app,如fu、 m等。 这些品种只能是一种详细的产品。 换言之,我可以把每一种产品都变成pple——fu、pple—— m。 它们需要两种不同的模式。

  • 在用户页上(即“how”观点),我需要能够展示产品及其种类(如果有的话)。 该系统需要了解这些品种与这一特定用户的特定产品有关。

在我收到第一份答复之后,我对下文的答复中描述的我的模型进行了修订。 每一种产品都属于一种产品,即:富吉只属于pple产品,而后者在产品表中是一种独特的补贴。 而且,产品有多种品种,即pple产品可能有5或10种不同的品种。

然而,由于每个用户可能拥有不同的产品/组合,因此它变得更加复杂。 例如,黄玉米贮存(用户)可能会有fu和 m(var)。 但是,普布利克斯谷物库(用户)可能拥有红利和香蕉(变)。

在用户网页上,如果用户选择了任何种类,我就能够打上用户携带的每一种产品,然后展示与每种产品相关的品种。

在我尝试下文所示代码时,我发现以下错误:没有界定的方法`用户'产品:

<% @user.products.each do |product| %>
   <% @user.user_products.find_by_product_id(product.id).varieties %>
<% end %>

另一方面,当我尝试你给我的其他选择时(列于下文),页面负荷和板块盘似乎是正确的,但网页上没有显示的品种,因为我进行三倍检查,数据库中有记录可与盘点相匹配。 详细情况

<% @user.products.each do |product| %>
   <% @user.varieties.find_by_product_id(product.id) %>
<% end %>    

该法典有以下 que:

User Load (0.7ms) SlectT* from “users” WHERE ("users”.id” = 2)

Variety Load (0.5ms) SlectT “varieties”.* from “varieties” INNER JOIN "user_product” ON "varieties.id = “user_products”,variety_id WHERE ("seasons.user_id = 2)

Rendering template within layouts/application
Rendering users/show

Product Load (0.7ms) SINET "products.* from "products” INNER JOIN "user_product” ON "products.id = “user_products”.product_id WHERE ((“用户_products.user_id = 2)

Variety Load (0.4ms) SlectT “varieties”.* from “varieties” INNER JOIN "user_product” ON “varieties”.variety_id WHERE (“varieties”.”product_id” = and 1) (“user_products.user_id = 2)

Variety Load (0.2ms) SlectT “varieties”.* from “varieties” INNER JOIN "user_products” ON “varieties”.variety_id WHERE (“varieties”.”product_id” = 2) and (“user_products.user_id = 2)

在上述情况下,Im 看望的用户是user_id=2,他在数据库中确实有产品_id=1和产品_id=2。 而且,在用户产品表中,我有几处记录,列出这一用户与这些产品中的每一产品有关并且与某些种类有关。 因此,我似乎喜欢在我看来展示一些成果,但我却不忘。

最后,当我尝试如下:

<% @user.products.each do |product| %>
   <%=h @user.user_products.find_by_product_id(product.id) %>
<% end %>

在我对每一记录的看法中显示:#<User_product:0x4211bb0>

最佳回答

They way I see it is that you don t have a many to many relationship to the products. You have it to the product of that particulary variety (if any). So in order to keep track of it, I would use an extra model. That way you would be able to keep the relationship between products and varieties as well.

模型:

class User < ActiveRecord::Base
  has_many :user_products, :dependent => :destroy
  has_many :products, :through => :user_products
  has_many :varieties, :through => :user_products
end

class UserProduct < ActiveRecord::Base
  belongs_to :user
  belongs_to :product
  belongs_to :variety
end

class Product < ActiveRecord::Base
  has_many :varieties
end

class Variety < ActiveRecord::Base
  belongs_to :product
end

控制器:

class UserProductsController < ApplicationController
    before_filter do 
        @user = User.find(params[ user_id ])
    end


    def create
      product = Product.find(params[ product_id ])
      variety = Variety.find(params[ variety_id ]) if params[ variety_id ]

      @user_product = UserProduct.new
      @user_product.user = user
      @user_product.product = product
      @user_product.variety = variety
      @user_product.save
    end

    def destroy
        # Either do something like this:
        conditions = {:user_id => @user.id}
        conditions[:product_id] = params[:product_id] if params[:product_id]
        conditions[:variety_id] = params[:variety_id] if params[:variety_id]

        UserProduct.destroy_all conditions
    end
end

The views: If you are not interested in grouping the varieties into the different products and just put them as a list it is enough with this:

# users/show.html.erb
<%= render @user.user_products %>

# user_products/_user_product.html.erb
<%= h user_product.product.name %> 
<%= h user_product.variety.name if user_product.variety %>

Otherwise something a bit more complicated have to be added. Some of it might be possible to put in the model and controller by using association proxies, but I can t help you there

# users/show
<% for product in @user.products do %>
    <%= product.name %>
    <%= render :partial =>  variety , 
        :collection => @user.varieties.find_by_product_id(product.id) %>
<% end %>

# users/_variety
<%= variety.name %> 

当然,把部分内容放在一边是没有必要的(例如,可能是一种微不足道的),但它有助于将不同部分分开,特别是如果你想增加更多的东西。

回答你的问题:

  1. Since UserProduct is a join model, you don t really need to keep track of it s individual id. You have the User, the Product and the Variety (in those cases it exists). That s all you need, that combination is unique and thus, you can find the record for deletion. Also, a join model should never be edited (provided that you don t have more attributes in it than these fields), It is either create or delete, since all it do is keep the associations.
  2. Since it is basically a viewing thing it is best to place it in the views. You could of course use the controller or the model to collect all the products and the varieties beforehand by doing something like this:

将所有逻辑推向控制员,模型可能不是一个好主意,因为它们不应知道(或谨慎)你想要显示数据。 因此,这只是一个充分准备的问题。

@products_for_user = []
@user.products.each do |product|
 collected_product = {:product => product, 
                      :varieties => @user.varieties.find_by_product_id(product.id)}
  @products_for_user << collected_product
end
问题回答

MikeH

您在此仅可打字,@user.user_product。 用户_products

When I try the code listed below in the show view, I get the following error: undefined method `user_product for #:

<% @user.products.each do |product| %>  
  <% @user.user_product.find_by_product_id(product.id).varieties %>  
<% end %>

您还可以考虑一种等级制度,在这种制度下,你才有“未来”、“Macintosh”和“Apples”等产品。

因此,“未来”和“Macintosh”将有一个一栏“表面——id”被 set到“Apples”。

只是一个想法。





相关问题