2010-02-05 42 views
51

Với mô hình AR sau, tôi muốn sắp xếp người dùng theo thứ tự abc theo tên cuối cùng khi đưa ra một xử lý cho một nhiệm vụ:Làm cách nào để đặt hàng has_many thông qua liên kết trong Ruby on Rails?

Tôi muốn để có được một công việc sau đó chuyển hướng đến người sử dụng được giao, và sắp xếp danh sách người dùng theo thứ tự abc.

tôi tiếp tục nghĩ rằng tôi sẽ có thể thêm mệnh đề :order-has_many :users, :through => :assignments như thế này:

#task.rb 
has_many :assignments 
has_many :users, :through => :assignments, :order => 'last_name, first_name' 

tuy nhiên điều này không hoạt động.

Làm cách nào để sắp xếp người dùng theo số last_name khi được giao một nhiệm vụ?

Trả lời

7

Điều này có phù hợp với bạn không?

# User.rb 

class User < ActiveRecord::Base 
default_scope :order => 'last_name ASC' 
... 
end 

Bạn có thể xác định phạm vi được đặt tên khác khi phân loại cần khác nhau.

http://ryandaigle.com/articles/2008/11/18/what-s-new-in-edge-rails-default-scoping

+2

Xin lỗi bạn đã gặp một câu hỏi cũ, nhưng điều này có thể liên quan đến người đọc trong tương lai: Một số plugin (ví dụ: actions_as_list) không hoạt động đúng với default_scope. – robinjam

+0

Cũng nhấn mạnh điều này vì tôi có vấn đề tương tự, nhưng cần phải sắp xếp trên một trường IN: qua bảng - điều tuyệt vời là default_scope cũng hoạt động trong bảng: và thông qua các bản ghi được truy xuất thông qua mối quan hệ đó sẽ tôn trọng thứ tự. – MBHNYC

36

Rails phiên bản 3.x:

has_many :users, :through => :assignments, :order => 'users.last_name, users.first_name' 

UPDATE: Đây chỉ hoạt động trong Rails 3.x (có thể trước đó quá). Đối với 4+, hãy xem các câu trả lời khác.

+0

Làm việc tốt cho tôi. Giải pháp làm sạch không ảnh hưởng đến các chức năng khác của mô hình được sắp xếp như câu trả lời đầu tiên. – barancw

+2

không hoạt động, nó nói: thứ tự không phải là chìa khóa. Dưới đây là câu trả lời từ chối IS đang hoạt động. – RohitPorwal

12

Phương pháp tiếp cận M.G.Palmer's hoạt động tốt, tuy nhiên tên bảng có liên quan. Có một cách tốt hơn để làm điều đó:

has_many :users, :through => :assignments, :order => [ :last_name, :first_name ] 
+0

nhưng nếu thứ tự được xác định bởi bảng kết nối thì sao? ví dụ. bài tập ... nhưng không xác định phạm vi mặc định cho bài tập .. – Tilo

2

Bạn cũng có thể tạo ra một cột 'SORT_ORDER' mới trên bàn chuyển nhượng, và thêm một phạm vi mặc định như

default_scope { order('sort_order desc')} 

để mô hình bài tập của bạn.

65

Kể từ khi lập luận tình trạng đang bị phản đối trong Rails 4, ta nên sử dụng phạm vi khối:

has_many :users, -> { order 'users.last_name, users.first_name' }, :through => :assignments 
+1

Có vẻ như hiện tại có lỗi trong Rails 4 với https://github.com/rails/rails/issues/17904 "Trong Rails 4.0 này, mệnh đề thứ tự đã bị bỏ qua. Trong Rails 4.1, SQL không hợp lệ được tạo ra. " – Nate

+0

Nó thậm chí không cung cấp cho tôi rằng, chỉ cần hoàn toàn bỏ qua các điều khoản đặt hàng không có thông báo. –

6

này làm việc cho tôi (Rails 4.2)

Áp dụng một trật tự trên thông qua bản đồ được không được bảo quản, aka này là không đủ để có thể loại ra lệnh:

has_many :disk_genre_maps, 
      -> {order('disk_genre_map.sort_order')}, 
      :inverse_of => :disk, 
      :dependent => :destroy, 
      :autosave => true 


has_many :genres, # not sorted like disk_genre_maps 
      :through => :disk_genre_maps, 
      :source  => :genre, 
      :autosave => true 

Vì vậy, tôi ghi đè này mỗi dụ:

def genres # redefine genres per instance so that the ordering is preserved 
    self.disk_genre_maps.map{|dgm|dgm.genre} 
end 

Để đảm rằng công việc cho các bài tập, điều này nên được một cái gì đó như thế này (chưa được kiểm tra)

def genres= some_genres 
    self.disk_genre_maps = some_genres.map.with_index do |genre, index| 
     DiskGenreMap.new(disk:self, genre:genre, sort_order:index) 
    end 
end 
2

Tôi đang sử dụng Rails (5.0.0.1) và có thể làm cho các loại với cú pháp này trong mô hình Nhóm của tôi rằng có nhiều người dùng thông qua group_users:

# Associations. 
has_many :group_users 
has_many :users, -> { order(:name) }, through: :group_users 

Điều chỉnh mã theo nhu cầu của bạn sẽ hoạt động.

Các vấn đề liên quan