查看问题底部的更新。
我不得不对我的应用程序进行一些调整以添加新功能,而我的更改似乎打破了以前完美运行的:uniq选项。
这是设置:
#User.rb
has_many:products,:through => :season,:uniq =>真正
has_many:variety,:through => :season,:uniq =>真正
has_many:season
#product.rb
has_many:season
has_many:users,:through => :season,:uniq =>真正
has_many:品种
#season.rb
belongs_to:产品
belongs_to:品种
belongs_to:用户
named_scope:by_product_name,:joins => :product,:order => 'products.name'
#variety.rb
belongs_to:产品
has_many:season
has_many:users,:through => :season,:uniq =>真的
首先,我想向您展示现在正在破坏的视图的先前版本,以便我们有一个比较的基线。下面的视图是提取属于用户的产品和品种。在下面的两个版本中,我为用户分配了相同的产品/品种,因此日志将查看完全相同的用例。
#user/show
<% @user.products.each do |product| %>
<%= link_to product.name, product %>
<% @user.varieties.find_all_by_product_id(product.id).each do |variety| %>
<%=h variety.name.capitalize %></p>
<% end %>
<% end %>
这很有效。它只显示每个产品中的一个,然后显示每个产品的品种。在下面的日志中,产品ID 1有3个相关的品种。产品ID 43没有。
以下是上述代码的日志输出:
Product Load (11.3ms) SELECT DISTINCT `products`.* FROM `products` INNER JOIN `seasons` ON `products`.id = `seasons`.product_id WHERE ((`seasons`.user_id = 1)) ORDER BY name, products.name
Product Columns (1.8ms) SHOW FIELDS FROM `products`
Variety Columns (1.9ms) SHOW FIELDS FROM `varieties`
Variety Load (0.7ms) SELECT DISTINCT `varieties`.* FROM `varieties` INNER JOIN `seasons` ON `varieties`.id = `seasons`.variety_id WHERE (`varieties`.`product_id` = 1) AND ((`seasons`.user_id = 1)) ORDER BY name
Variety Load (0.5ms) SELECT DISTINCT `varieties`.* FROM `varieties` INNER JOIN `seasons` ON `varieties`.id = `seasons`.variety_id WHERE (`varieties`.`product_id` = 43) AND ((`seasons`.user_id = 1)) ORDER BY name
好的,所以上面的所有内容都是以前的版本,效果很好。在新版本中,我在连接表中添加了一些名为seasons
的列,并创建了一组查询这些列的自定义方法。因此,我对您在上面看到的视图代码进行了以下更改,以便我可以在seasons
模型上访问这些方法:
<% @user.seasons.by_product_name.each do |season| %>
<%= link_to season.product.name, season.product %>
#Note: I couldn't get this loop to work at all, so I settled for the following:
#<% @user.varieties.find_all_by_product_id(product.id).each do |variety| %>
<%=h season.variety.name.capitalize %>
<%end%>
<%end%>
以下是该日志输出:
SQL (0.9ms) SELECT count(DISTINCT "products".id) AS count_products_id FROM "products" INNER JOIN "seasons" ON "products".id = "seasons".product_id WHERE (("seasons".user_id = 1))
Season Load (1.8ms) SELECT "seasons".* FROM "seasons" INNER JOIN "products" ON "products".id = "seasons".product_id WHERE ("seasons".user_id = 1) AND ("seasons".user_id = 1) ORDER BY products.name
Product Load (0.7ms) SELECT * FROM "products" WHERE ("products"."id" = 43) ORDER BY products.name
CACHE (0.0ms) SELECT "seasons".* FROM "seasons" INNER JOIN "products" ON "products".id = "seasons".product_id WHERE ("seasons".user_id = 1) AND ("seasons".user_id = 1) ORDER BY products.name
Product Load (0.4ms) SELECT * FROM "products" WHERE ("products"."id" = 1) ORDER BY products.name
Variety Load (0.4ms) SELECT * FROM "varieties" WHERE ("varieties"."id" = 2) ORDER BY name
CACHE (0.0ms) SELECT * FROM "products" WHERE ("products"."id" = 1) ORDER BY products.name
Variety Load (0.4ms) SELECT * FROM "varieties" WHERE ("varieties"."id" = 8) ORDER BY name
CACHE (0.0ms) SELECT * FROM "products" WHERE ("products"."id" = 1) ORDER BY products.name
Variety Load (0.4ms) SELECT * FROM "varieties" WHERE ("varieties"."id" = 7) ORDER BY name
CACHE (0.0ms) SELECT * FROM "products" WHERE ("products"."id" = 43) ORDER BY products.name
CACHE (0.0ms) SELECT count(DISTINCT "products".id) AS count_products_id FROM "products" INNER JOIN "seasons" ON "products".id = "seasons".product_id WHERE (("seasons".user_id = 1))
CACHE (0.0ms) SELECT "seasons".* FROM "seasons" INNER JOIN "products" ON "products".id = "seasons".product_id WHERE ("seasons".user_id = 1) AND ("seasons".user_id = 1) ORDER BY products.name
CACHE (0.0ms) SELECT * FROM "products" WHERE ("products"."id" = 1) ORDER BY products.name
CACHE (0.0ms) SELECT * FROM "products" WHERE ("products"."id" = 1) ORDER BY products.name
CACHE (0.0ms) SELECT * FROM "varieties" WHERE ("varieties"."id" = 8) ORDER BY name
我有两个问题:
(1):uniq选项不适用于products
。页面上显示同一产品的三个不同版本
(2):uniq选项不适用于varieties
。我还没有设置验证,如果用户两次输入相同的品种,它会出现在页面上。在之前的工作版本中,情况并非如此。
我需要的结果是只显示任何给定ID的产品,并且与该ID相关的所有品种都会显示这种独特的产品。
有一件事对我来说是最近日志输出中的sql调用。它为不同的通话添加了“计数”。我不确定它为什么会这样做,或者它是否表明存在问题。我发现这个未解决的灯塔票似乎可能是相关的,但我不确定它是否是同一个问题:https://rails.lighthouseapp.com/projects/8994/tickets/2189-count-breaks-sqlite-has_many-through-association-collection-with-named-scope
我认为问题在于每个季节都会调用一次named_scope。在named_scope中需要有一些东西可以按季节id缩小返回的产品。
现在正在发生的事情是:
user =给我用户
四季=给我用户的季节(比如,用户有3个季节)
产品=给我产品
产品+ =给我产品
产品+ =给我产品
给我每个产品
所以发生的事情并不是uniq正在破坏,而是命名范围上没有分隔符。 (我认为)。
我尝试了以下操作,但它抛出了这个异常:Hash的奇数列表
named_scope :by_product_name, lambda { |seasons| { season_ids = seasons.map { |season| season.id }; :joins => :product, :conditions => { :seasons { :id => season_id } } :order => 'products.name' } }
想法?
好的,现在我想也许它根本不是命名范围的。
在#user/show
中,我刚刚更改了循环以绕过命名范围:
<% @user.seasons.each do |season| %>
<%= link_to season.product.name, season.product %>
#Note: I couldn't get this loop to work at all, so I settled for the following:
#<% @user.varieties.find_all_by_product_id(product.id).each do |variety| %>
<%=h season.variety.name.capitalize %>
<%end%>
<%end%>
以上不使用命名范围,但我仍然得到相同的结果。换句话说,我仍然看到每个产品的所有实例,而不仅仅是一个。
上面创建第一个循环的代码与我在本问题顶部列出的原始代码相同。不同之处在于此代码循环遍历seasons
以点击products
,而我的原始代码循环遍历products
。这种差异是问题隐藏的地方,但我不知道如何修复它。
另外,我在原来的问题中提到,我也无法让变量循环工作。您可以在上面的代码中看到注释的行。当循环遍历季节而不是产品时,当Rails遇到变量循环时,它会抛出一个名称错误:
undefined local variable or method `product'
似乎这可能是同一问题的另一个症状?
还有其他想法吗?
答案 0 :(得分:0)
我认为问题是lambda的格式化。我显然无法运行SQL,但是下面的lambda会创建一个适当的哈希:
lambda { |seasons| season_ids = seasons.map { |season| season.id }; { :joins => :product, :conditions => { :seasons => { :id => season_ids } }, :order => 'products.name' } }
具有ID 1和2的两个赛季的该呼叫的输出是:
{:joins=>:product, :conditions=>{:seasons=>{:id=>[1, 2]}}, :order=>"products.name"}