8

Thông thường tôi sẽ không lưu trữ các đối tượng trong phiên Rails nhưng tôi đang sử dụng thư viện yêu cầu điều này. Tôi đã chạy vào một vấn đề rất lạ, nơi một đối tượng được lưu trữ xuất hiện như một String sau khi chuyển hướng.Đối tượng được lưu trong phiên Rails trở thành một String?

Để sinh sản tôi đã tạo ra một mẫu Rails 4.1 ứng dụng

$ rails new session-test

gia tăng một bộ điều khiển kiểm tra:

class HomeController < ApplicationController 
    def index 
    logger.debug "session[:customer]: #{session[:customer]}" 
    logger.debug "session[:customer].name: #{session[:customer].name}" 
    end 

    def from 
    Struct.new 'Customer', :name, :address 
    session[:customer] = Struct::Customer.new 'Dave', '123 Main' 
    redirect_to :action => :index 
    end 
end 

thiết lập các tuyến đường:

Rails.application.routes.draw do 
    get 'home/index' 
    get 'home/from' 
    root 'home#index' 
end 

Sau đó, tôi cháy lên Rails

$ bundle exec rails server

và nhấn localhost: 3000/home/từ trong trình duyệt:

Started GET "/home/from" for 127.0.0.1 at 2014-04-09 21:20:25 -0700 
Processing by HomeController#from as HTML 
Redirected to http://localhost:3000/home/index 
Completed 302 Found in 18ms (ActiveRecord: 0.0ms) 


Started GET "/home/index" for 127.0.0.1 at 2014-04-09 21:20:25 -0700 
Processing by HomeController#index as HTML 
session[:customer]: #<struct Struct::Customer name="Dave", address="123 Main"> 
Completed 500 Internal Server Error in 2ms 

NoMethodError (undefined method `name' for "#<struct Struct::Customer name=\"Dave\", address=\"123 Main\">":String): 
    app/controllers/home_controller.rb:4:in `index' 

Tôi không có ý tưởng tại sao đối tượng này là nhận được dịch là một String ...

Nó xuất hiện phải làm gì với loại cửa hàng phiên của cookie_store vì nếu tôi thay đổi

session_store.rb từ

Rails.application.config.session_store :cookie_store, key: '_session-test_session'

để

Rails.application.config.session_store :cache_store

nó hoạt động!

Bất kỳ ý tưởng nào?

+0

Thư viện được đề cập là đá quý shopify_app được rất nhiều nhà phát triển sử dụng. Tôi đồng ý đó là một ý tưởng tồi để lưu trữ đối tượng trong phiên Rails vì một số lý do nhưng đó là những gì đá quý này làm: https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/templates /app/controllers/sessions_controller.rb#L12-L13 Điều tôi đang băn khoăn là tại sao điều này lại bị bẻ cong trong Rails 4.1? Tôi không thấy nó xảy ra trong ứng dụng mẫu của họ là 3.2: https://github.com/Shopify/embedded-app-example –

Trả lời

5

Bạn không thể lưu trữ các đối tượng trong phiên Rails. Đó là một kho khóa-giá trị chỉ chấp nhận chuỗi bởi vì, thường xuyên hơn không, nó được đóng gói và gửi cho khách hàng dưới dạng một cookie được mã hóa.

Nó không phải là một bãi rác cho những thứ bạn có thể cần. Hãy chú ý đến số lượng rác bạn nhồi nhét trong đó vì bạn càng dựa vào phiên, cookie càng lớn thì khách hàng sẽ phải quay trở lại máy chủ của bạn cho mọi yêu cầu.

Cần xem xét các tiêu đề trong công cụ kiểm tra mạng của trình duyệt của bạn để xem mức độ yêu cầu của bạn.

Nếu bạn thực sự cần phải duy trì điều gì đó trong đó, hãy sử dụng định dạng mã hóa thân thiện với chuỗi như JSON để đảm bảo bạn có thể lấy lại dữ liệu ở định dạng có thể sử dụng.

Tôi cũng rất do dự khi sử dụng số cache_store, không được chia sẻ trên các phiên bản ứng dụng khác nhau của bạn. Các đối tượng Ruby chỉ tồn tại trong bối cảnh của một tiến trình duy nhất, vì vậy các yêu cầu khác, thường xuyên hơn sẽ không tấn công một số quá trình ngẫu nhiên, sẽ không thể sử dụng điều này một cách dễ dàng.

Cửa hàng cookie mặc định là đáng tin cậy nhất. Những người khác mà chia sẻ giữa các quá trình phụ thuộc vào các dịch vụ bổ sung đang hoạt động (Memcached, Redis, vv) nhưng hầu hết những người dictate một chính sách dây chỉ là tốt.

+0

Thư viện được đề cập là gem shopify_app được rất nhiều devs sử dụng. Tôi đồng ý đó là một ý tưởng tồi để lưu trữ đối tượng trong phiên Rails vì một số lý do nhưng đó là những gì đá quý này làm: https://github.com/Shopify/shopify_app/blob/master/lib/generators/shopify_app/templates /app/controllers/sessions_controller.rb#L12-L13 Điều tôi đang băn khoăn là tại sao điều này lại bị bẻ cong trong Rails 4.1? Tôi không thấy nó xảy ra trong ứng dụng mẫu của họ là 3.2: https://github.com/Shopify/embedded-app-example –

+0

Bạn có thể lưu trữ mọi thứ một cách đáng tin cậy nếu chúng được đăng theo thứ tự. Nếu không nó là hit và bỏ lỡ. Tôi không chắc tại sao một người nào đó sẽ viết mã phụ thuộc vào nó làm việc chống lại tất cả các tỷ lệ cược. – tadman

0

Tôi đã gặp sự cố tương tự với ứng dụng Shopify của mình và đã dành rất nhiều thời gian để gỡ lỗi. Dựa trên lời giải thích chính xác nếu không thuyết phục của tadman, tôi đã có thể làm việc xung quanh nó bởi Marshalling đối tượng phiên. Nó chỉ yêu cầu 3 dòng mã để thay đổi:

login_protection.rb: 12: ShopifyAPI :: Base.activate_session (Nguyên soái :: phiên tải [: shopify]) login_protection.rb: 25: Marshal :: load session [ : Shopify]

sessions_controller.rb: 13: phiên [: Shopify] = Marshal :: bãi (sess)

tôi đăng này trên diễn đàn Shopify và hy vọng họ sẽ phát hành một bản cập nhật sớm. Đối với những gì nó có giá trị, tôi nghĩ rằng cách cũ, trong khi triết học "sai", làm việc một cách chính xác trong mọi phiên bản của Rails lên đến 4.1.

4

Khắc phục là thực hiện tuần tự hóa và khử tuần tự một cách rõ ràng, theo cách thủ công.

ví dụ:

# storing... 
session[:customer] = (Struct::Customer.new 'Dave', '123 Main').to_yaml 

# retrieving... 
customer = YAML.load(session[:customer]) 

Đối shopify_app đá quý, thấy những thay đổi tập tin trong yêu cầu kéo https://github.com/Shopify/shopify_app/pull/90/files và áp dụng phù hợp để ứng dụng hiện tại của bạn.

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