2010-05-29 28 views
15

Tôi muốn viết named scope để nhận bản ghi từ id của nó.Làm thế nào tôi có thể đặt named_scope trong Rails trả lại một giá trị thay vì một mảng?

Ví dụ: tôi có một kiểu gọi là Event và tôi muốn mô phỏng Event.find(id) khi sử dụng named_scope để có tính linh hoạt trong tương lai.

tôi đã sử dụng mã này trong mô hình của tôi:

named_scope :from_id, lambda { |id| {:conditions => ['id= ?', id] } } 

và tôi gọi nó từ bộ điều khiển của tôi như Event.from_id(id). Nhưng vấn đề của tôi là nó trả về một mảng các đối tượng Event thay vì chỉ một đối tượng.

Vì vậy, nếu tôi muốn có được tên sự kiện, tôi phải viết

event = Event.from_id(id) 
event[0].name 

trong khi những gì tôi muốn là

event = Event.from_id(id) 
event.name 

Tôi có làm điều gì đó sai ở đây?

Trả lời

10

Vì Damien đề cập, việc sử dụng phạm vi tùy chỉnh chỉ để tra cứu bằng ID không được khuyến khích. Nhưng để trả lời câu hỏi của bạn:

Tìm bản ghi với named_scope sẽ luôn trả về đối tượng ActiveRecord::NamedScope::Scope, hoạt động giống như một mảng. Nếu có chỉ là một hồ sơ duy nhất được trả về bởi truy vấn của bạn, bạn có thể sử dụng phương pháp first để có được những đối tượng ActiveRecord trực tiếp, như thế này:

event = Event.from_id(id).first 
event.name # will work as you expect 
+0

hi Jimmy Cảm ơn câu trả lời nhanh.Tại sao tôi muốn có một phạm vi được đặt tên là (như tôi đã đề cập trong bình luận của Damien) vì sau này tôi có thể chỉ nhận được các sự kiện hoạt động Vì vậy, tôi chỉ có thể thay đổi phạm vi được đặt tên bằng cách phá vỡ mã hiện có (như chỉ thêm hoạt động = 1) Xin vui lòng cho tôi biết ý kiến ​​của bạn cổ vũ, cùng một – sameera207

5

Không cần sử dụng phạm vi tại đây. Bạn chỉ có thể làm Event.find_by_id id.
Sự khác biệt giữa findfind_by_id là số đầu tiên sẽ tăng ActiveRecordNotFoundException nếu bản ghi không tồn tại. Cái thứ hai sẽ chỉ trả lại không.

Viết phạm vi để nhận bản ghi theo id của nó là id rất xấu vì nó là cái gì đó đã được cung cấp nguyên bản bởi đường ray.

+0

Hi Damien, cảm ơn bạn đã trả lời nhanh. Tại sao tôi muốn có điều này như một phạm vi được đặt tên là vì sau này tôi có thể chỉ nhận được các sự kiện hoạt động Vì vậy, tôi chỉ có thể thay đổi phạm vi đã đặt tên bằng cách vi phạm mã hiện tại (như chỉ thêm hoạt động = 1) hãy cho tôi biết ý kiến ​​của bạn cổ vũ, sameera – sameera207

+1

@sameera bạn chỉ có thể thêm phương thức chung chung ('def ... end'); nó không phải là một phạm vi được đặt tên. –

10

Trong trường hợp này tôi muốn tạo ra một phương pháp học

def self.from_id(id) 
    self.find(id).first 
end 

Ví dụ khác:

Các phương pháp như sau này tốt hơn là named_scope. Bạn có thể gọi Invoice.number.next, tốt hơn named_scope trả lại Invoice.number[0].next.

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