2011-08-27 29 views
15

Với Rails 3, Làm thế nào bạn có thể đặt một biến session trong một mô hìnhThiết lập một biến Session trong một mô hình

session[:cannot_reason] = "no such item" 

Tôi muốn thiết lập ở trên trong mô hình của tôi sử dụng. Hiện tại, tôi nhận được lỗi này:

undefined local variable or method `session' for #<User:0x00000102eb9c38> 

Ý tưởng? Cảm ơn

Trả lời

30

Có một số không cần thiết hàng-culting về hay không mô hình nên có quyền truy cập vào dữ liệu phiên. Tôi nghĩ rằng điều này là ngớ ngẩn, vì phiên thực sự chỉ là một dạng lưu trữ lâu dài khác (mặc dù khung thời gian ngắn hơn nhiều) và trong Rails, có vẻ như không có đối tượng miền của bạn cũng có thể tự tồn tại.

đó đang được nói, cách không phải là rất sạch sẽ để làm điều đó sẽ được vượt qua băm phiên như một tham số vào phương pháp dùng mà sẽ hoạt động trên nó:

class User < ... 
    def mymethod(session, count) 
    session[:count] = count 
    end 
end 

Trong điều khiển của bạn, bạn sẽ sau đó làm điều gì đó như:

def update 
    # ... 
    user.mymethod(session, count) 
end 

Tưởng tượng rằng mymethod đang triển khai một số logic kinh doanh, điều này sẽ thay đổi session băm một cách thích hợp. Bạn không cần phải vượt qua hàm băm session trở lại bộ điều khiển vì Ruby truyền xung quanh các tham chiếu đến các đối tượng (giống như một Hash) - các sửa đổi được thực hiện một cách triệt để đối với các đối tượng được tham chiếu đó.

Lời khuyên: Ví dụ trên, theo ý kiến ​​của tôi, có mùi. Điều này là do User là một mô hình ActiveRecord (tôi giả định) vẫn tồn tại trong cơ sở dữ liệu và chúng tôi đang thêm hành vi làm cho nó cũng tồn tại đối với cookie phiên. Với tôi, điều này vi phạm SRP và nên tránh.

Cách tôi thực hiện điều này sẽ là trích xuất logic lưu trữ phiên ra thành một đối tượng miền riêng biệt đóng gói lý do cho sự tồn tại của nó. Có lẽ, ví dụ, count không chỉ là một "đếm", đó là tổng số lượng các mục trong giỏ hàng tạm thời của người dùng.

class TemporaryCart 
    def initialize(session) 
    @session = session 
    end 

    def add_item 
    # ... other item adding logic 
    @session[:temporary_cart][:num_items] += 1 
    end 
end 

Bây giờ điều khiển của bạn sẽ trông như thế này:

def update 
    # ... 
    TemporaryCart.new(session).add_item 
end 

Đây là nhiều hơn nữa tiết lộ và mở ra cánh cửa cho một cách rõ ràng để trừu tượng ra mã truy cập phiên làm việc nếu bạn thấy mình sử dụng lưu trữ phiên rất nhiều . Cũng lưu ý rằng tôi đã đặt tên cho dữ liệu trong phiên băm (nhưng không hiển thị việc triển khai này). Tôi khuyên bạn nên làm điều này để bạn không bước vào ngón chân của riêng bạn khi thêm dữ liệu khác.

7

Tóm lại, bạn không thể. Theo thiết kế, các mô hình không có quyền truy cập vào cookie và phiên. Nếu bạn truy cập các mục trong phiên từ mô hình của mình, bạn sẽ cần chuyển chúng một cách rõ ràng từ bộ điều khiển.

+2

Làm cách nào bạn vượt qua chúng? Chỉnh sửa tâm trí với một ví dụ? Cảm ơn – AnApprentice

+4

mô hình không nên sử dụng Phiên, điều này là sai ở nhiều cấp độ –

5

Đối tượng phiên không hiển thị trong các mô hình. Hoặc là chuyển nó thành một tham số cho một phương thức trong mô hình của bạn (IMHO bad) hoặc định nghĩa một phương thức trong mô hình của bạn trả về những gì bạn muốn và lưu nó trong phiên làm việc (từ bộ điều khiển của bạn).

class User < ... 
    def item_status 
    return :no_such_item 
    end 
end 

Trong điều khiển của bạn

session[:item_status] = current_user.item_status 
Các vấn đề liên quan