2012-08-17 64 views
4

我寫嗨,但SO不會讓它,所以我寫更長的句子:)嗨,順便說一句。使用範圍除外不工作Rails

它看起來像我的範圍不起作用。

我寫的範圍:

scope :ordered, ->(field, order) { except(:order).order("#{field} #{order}") }

但它返回當檢查下面的SQL:

irb >p.levels.ordered("name", "ASC").to_sql 
=> "SELECT \"levels\".* FROM \"levels\" WHERE (\"levels\".pie_id = 6 AND (\"levels\".\"parent_id\" = 0)) ORDER BY position ASC, name ASC" 

注:position ASC不應該存在

但它工作時在我的示波器之前添加除外...

irb > p.levels.except(:order).ordered("name", "ASC").to_sql 
=> "SELECT \"levels\".* FROM \"levels\" WHERE (\"levels\".pie_id = 6 AND (\"levels\".\"parent_id\" = 0)) ORDER BY name ASC" ` 

除了在範圍內可用嗎?或者你看到有什麼可以幫助我嗎?

紅寶石1.9.2p290

滑軌3.0.14

THX

回答

0

方法的順序可能是錯誤的。

應該寫order("#{field} #{order}").except(:order)

看到rails guide

+0

我想什麼實現就是重置默認的訂單條件來設置一個新的訂購之後。您顯示的方式是刪除您剛剛設置的訂單。然後,查詢將不會有任何訂單條件。看到你給的鏈接。 Thx無論如何 – Bachet 2012-08-19 21:11:59

1
,美在模型中定義

添加範圍

scope :ordered, ->(field, order) { except(:order).order("#{field} #{order}") } 

嘗試不同的組合和所有工作

a.inspection_serial_numbers.ordered('part_serial_number', 'DESC').except(:order).ordered('id', 'DESC').to_sql 

=> "SELECT `inspection_serial_numbers`.* FROM `inspection_serial_numbers` WHERE `inspection_serial_numbers`.`inspection_master_id` = 1 ORDER BY id DESC" 

a.inspection_serial_numbers.ordered('part_serial_number', 'DESC').except(:order).ordered('id', 'DESC').except(:order).ordered('is_active', 'ASC').to_sql 

=> "SELECT `inspection_serial_numbers`.* FROM `inspection_serial_numbers` WHERE `inspection_serial_numbers`.`inspection_master_id` = 1 ORDER BY is_active ASC" 

即使ü結合'有序'範圍與「除了」在許多次,最後「下令」任何組合範圍用於訂購

a.inspection_serial_numbers.ordered('part_serial_number', 'DESC').ordered('id', 'ASC').except(:order).ordered('id', 'DESC').to_sql 

=> "SELECT `inspection_serial_numbers`.* FROM `inspection_serial_numbers` WHERE `inspection_serial_numbers`.`inspection_master_id` = 1 ORDER BY id DESC" 

BUF它ü要刪除所有範圍,使用「無範圍」

a.inspection_serial_numbers.ordered('id', 'ASC').unscoped.ordered('part_serial_number', 'DESC').to_sql 

=> "SELECT \"inspection_serial_numbers\".* FROM \"inspection_serial_numbers\" ORDER BY part_serial_number DESC" 

請參閱http://apidock.com/rails/ActiveRecord/SpawnMethods/excepthttp://apidock.com/rails/ActiveRecord/Base/unscoped/class

+0

嘿,它似乎也很好,我會盡快看看。 Thx回答 – Bachet 2012-09-18 09:29:31

3

您可能已經想通過使用reorder可以實現您的目標。所以這裏是我的理論爲什麼reorder工作和except沒有。

這一點很重要,那方法,如orderwhereexcept通過的ActiveRecord::Relation情況處理,而示波器,例如你的例子中的orderedActiveRecord::Relation的實例委託給你的模型類。

some_relation.order(:x)方法只需將some_relation的新副本與:x添加到其列表order_values。同樣,some_relation.except(:order)將返回空行order_valuessome_relation的副本。只要調用鏈包含這種關係方法,except就像我們預期的那樣工作。

的範圍方法,當範圍爲lambda返回關係中實現的呼叫,最終由scoped由拉姆達返回關係恢復模型的關係合併:

scopes[name] = lambda do |*args| 
    options = scope_options.is_a?(Proc) ? scope_options.call(*args) : scope_options 

    relation = if options.is_a?(Hash) 
    scoped.apply_finder_options(options) 
    elsif options 
    scoped.merge(options) # <- here options is what returned by your :ordered lambda 
    else 
    scoped 
    end 

    extension ? relation.extending(extension) : relation 
end 

merge不如果僅對正在合併的關係之一執行,則保留except的效果。如果我們合併ab,並且b沒有訂單設置,但是a確實有效,那麼結果仍然有序。現在reorder解決它的一個訣竅:它設置特殊標誌reorder_flag關係,它控制merge如何攜帶order_values

這是我的測試樣本。我使用default_scopeProduct#scoped注入訂單。在你的例子中,訂單可能被注入Level#scoped的聯繫人Pie,看起來像has_many :levels, :order => 'position'

class Product < ActiveRecord::Base 
    default_scope order('id DESC') 
    scope :random_order, lambda { 
    r = order('random()') 
    puts "from lambda: " + r.order_values.inspect 
    r 
    } 
end 

# in console: 

>> Product.scoped.order_values 
=> ["id DESC"] 

>> Product.random_order.order_values 
from lambda: ["id DESC", "random()"] 
=> ["id DESC", "id DESC", "random()"] 

# now if I change the first line of lambda to 
# r = except(:order).order('random()') 

>> Product.random_order.order_values 
from lambda: ["random()"] 
=> ["id DESC", "random()"] 

正如你所看到的,因爲事實上,Product.scopedid DESC秩序,儘管它是由範圍返回關係清除它出現在結果。

這裏是鏈接到相關源的列表:

+0

嘿,這似乎很好,我會盡快看看。 Thx回答 – Bachet 2012-09-18 09:28:44