2013-08-25 43 views
6

Sau khi nhận tất cả các giá trị từ mô hình, tôi muốn thêm thuộc tính tùy chỉnh khác vào lớp ActiveRecord (thuộc tính này không phải là cột trong db) để tôi có thể sử dụng nó trong chế độ xem, nhưng đường ray không cho phép tôi thêm. Tôi nên thêm gì vào lớp mô hình của nó?Cách thêm thuộc tính mới vào ActiveRecord

@test.all 

@test.each do |elm| 
    elm[:newatt] = 'added string' 
end 

lỗi:

can't write unknown attribute `newatt' 
+0

Bạn muốn làm gì với ứng dụng này? Chỉ có một phạm vi hoặc bạn có muốn lưu nó vào cơ sở dữ liệu? – Mindbreaker

+0

Tôi không muốn lưu nó vào cơ sở dữ liệu. Tôi đang làm một số xử lý trong đó mỗi (xem mã cập nhật), và tôi muốn thêm một số thông tin bổ sung cho từng yếu tố. Nó sẽ chỉ được sử dụng trong chế độ xem. – Ladiko

+0

Bản sao có thể có của [Thêm các nhân viên trợ giúp thời gian chạy thêm vào đối tượng activerecord] (http://stackoverflow.com/questions/7584592/adding-extra-run-time-attribs-to-an-activerecord-object) – mlt

Trả lời

4

Xác định thuộc tính ảo như biến Ví dụ:

attr_accessor :newattr 
+0

Không làm việc, xin vui lòng xem mã cập nhật. – Ladiko

+2

'elm.newatt = 'chuỗi đã thêm' ' –

+0

Hãy làm như Jesse chỉ ra trong bình luận của mình – boulder

8

thử này

class Test < ActiveRecord::Base 
    attr_accessor :newattr 
end 

bạn có thể truy cập vào nó như

@test = Test.new 
@test.newattr = "value" 

Như bạn có thể thấy thuộc tính này, không phải là băm. do đó, nó sử dụng cú pháp .. Tuy nhiên, nếu bạn cần nó để hành xử như một hash bạn có thể làm điều này mà không cần xác định một thuộc tính mới

@test.all 
@test.each do |elm| 
    new_elm = {} 
    new_elm[:newatt] = 'added string' 
end 

Cuối cùng, tôi không chắc chắn chính xác những gì bạn đang cố gắng làm. nếu điều này không có ý nghĩa với bạn, vui lòng rephrase câu hỏi của bạn để chúng tôi có thể hiểu được vấn đề tốt hơn.

2

Tôi nghĩ bạn định gán @test cho truy vấn ActiveRecord, đúng không? Hãy thử:

@test = MyARClass.select("*, NULL as newatt") 
@test.each {|t| t[:newatt] = some_value} 

Một giải pháp có liên quan là làm cho nó một phương pháp lớp singleton, mặc dù bạn sẽ phải nhảy dù nhiều hoops để làm cho nó có khả năng ghi và tôi bằng trực giác cảm thấy như thế này có thể phải gánh chịu chi phí hơn

@test = MyARClass.all 
@test.each do t 
    def t.newatt 
    some_value 
    end 
end 

Sử dụng phương pháp thứ hai, tất nhiên bạn sẽ truy cập nó qua @ test.first.newatt, thay vì @ test.first [: newatt]. Bạn có thể thử định nghĩa lại t. [] Và t. [] =, Nhưng điều này bắt đầu trở nên thực sự lộn xộn.

2

Nếu nó thực sự chỉ là tạm thời nó không phải là trong đối tượng:

@test.all 
@test_temp = [] 

@test.each do |elm| 
    @test_temp << {:elm => elm, :newatt => 'added string'} 
end 

Nếu không, có cũng good answers here đang có.

3

Nếu bạn muốn điều này chỉ dành cho quan điểm của mình và không có bất kỳ mục đích nào khác thì bạn không cần phải thêm attr_accessor

@test.all.select('tests.*, "added string" as newattr') 

đây bạn đang thêm thuộc tính newattr cho sản lượng truy vấn của ActiveRecord với một giá trị 'được thêm vào chuỗi '

1
@test.all 

@test.each do |elm| 
    write_attribute(:newatt, "added string") 
end 
0

Tôi đã gặp vấn đề tương tự. và bỏ qua thành công bằng cách sử dụng instance_eval

@test.all 

@test.each do |elm| 
    elm.instance_eval { @newatt = 'added string' } 
end 

bình thường nó không gặp vấn đề gì khi sử dụng attr_accessor. nó xuất hiện khi ghi đè DSL khác "newattr =" gây ra vấn đề. Trong trường hợp của tôi, đó là tiền "kiếm tiền: newatt"

Sử dụng rõ ràng write_attribute không hoạt động vì đó là lý do để tăng ngoại lệ trong đường ray 4.x

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