2010-11-13 35 views
12

Tôi hiện đang trải qua hướng dẫn RoR (http://railstutorial.org/chapters/sign-in-sign-out#sec:signin_success là phần có liên quan) có vẻ khá tốt, mặc dù tôi đã gặp sự cố sau khi cố gắng xem trang web mẫu .biến cục bộ hoặc phương thức không xác định 'current_user'

Extracted source (around line #10): 

7:   <li><%= link_to "Home", root_path %></li> 
8:   <li><%= link_to "About", about_path %></li> 
9:   
10:    <% if signed_in? %> 
11:     <li><%= link_to "Profile", current_user %></li> 
12:     <li><%= link_to "Sign out", signout_path, :method => delete %></li> 
13:    <% else %> 

Như bạn có thể thấy, sự cố bắt nguồn từ phương pháp "signed_in?" Của tôi đó là nghĩa vụ phải kiểm tra xem người dùng đã đăng nhập hay không bằng cách kiểm tra xem biến CURRENT_USER được thiết lập (Tôi đã bao gồm phần còn lại của mã từ helper để đưa ra một bối cảnh, lời xin lỗi):

module SessionsHelper 

    def sign_in(user) 
    cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
    current_user = user 
    end 

    def sign_out 
    cookies.delete[:remember_token] 
    current_user = nil 
    end 

    def current_user= (user) 
    @current_user ||= user_from_remember_token 
    end 

    def signed_in? 
    !current_user.nil? 
    end 

    private 

    def user_from_remember_token 
     User.authenticate_with_salt(*remember_token) 
    end 

    def remember_token 
     cookies.signed[:remember_token] || [nil, nil] 
    end 

end 

Từ sự hiểu biết của tôi, .nil? là một phương pháp kiểm tra xem một đối tượng đã được xác định hay chưa và do đó đối tượng không được xác định sẽ không tạo ra lỗi mà đúng hơn là trả về false? Tôi đã tìm kiếm hướng dẫn cho tất cả các trường hợp của current_user (trước khi kiểm tra xem liệu có ai khác gặp vấn đề này với thành công nhỏ không) và mã của tôi có vẻ đúng nên tôi hơi bối rối và nếu có ai có thể giúp tôi hiểu cách biến Ruby đáng lẽ phải được truy cập và tại sao mã của tôi không hoạt động tôi sẽ biết ơn nhất.

Edit:

Tôi không chắc chắn nếu nó quan trọng với phạm vi là như tôi chỉ mới bắt đầu cả hai Rails và Ruby, tuy nhiên SessionsHelper helper đang được sử dụng bởi bộ điều khiển và quan điểm người dùng của tôi (nó bao gồm trong ứng dụng của tôi bộ điều khiển)

Trả lời

7

Tôi đã gặp phải vấn đề tương tự này & vì lý do đó. Bạn đã bỏ qua một phần các hướng dẫn trong 'Liệt kê 9.16'.

def current_user= (user) 
    @current_user ||= user_from_remember_token 
end 

Bạn phải thay đổi điều này thành những điều sau đây.

def current_user 
    @current_user ||= user_from_remember_token 
end 

Bạn cũng sẽ muốn thay đổi tất cả các phiên bản * self. * Current_user thành * @ * current_user.

Khi bạn thực hiện việc này, (các) lỗi được giải quyết.

2

Nil? phương pháp sẽ không kiểm tra xem một biến hay phương thức được định nghĩa. Nó chỉ là kiểm tra xem nó được định nghĩa là một đối tượng nil hay không. Ruby đi lên chuỗi tổ tiên cho SessionsHelper và cuối cùng xác định rằng current_user không được định nghĩa ở bất cứ nơi nào (nó cuối cùng sẽ kết thúc tại Kernel # method_missing) và sau đó ném một lỗi. Cách nhanh nhất để giải quyết vấn đề là:

#app/helpers/sessions_helper.rb 
def current_user 
    @current_user ||= false 
end 
+0

hoặc tôi tin rằng bạn có thể thực hiện "@current_user || = user_from_remember_token || false" nếu bạn muốn phù hợp hơn với mã hiện tại của mình. – JackCA

+0

Trong khi đó chắc chắn dừng lỗi, nó liên tục trở về sai. Tôi đoán có thể có vấn đề với việc đăng nhập của tôi vào các phương thức khiến cho current_user không bao giờ được định nghĩa nên có lẽ tốt nhất cho tôi để xem nó sau một đêm ngủ ngon. – djlumley

2

Tôi hỏi một người bạn và sửa lỗi của tôi. Tôi nghĩ rằng một phần lớn sai lầm của tôi đến từ việc không hoàn toàn quen thuộc với phạm vi biến đổi trong Ruby và quên rằng mọi thứ đều là một đối tượng và do đó phương thức current_user = (user) đã ghi đè hàm gán.

Giải pháp của bạn tôi là thay đổi phạm vi của current_user thành biến cố định (để có thể sử dụng đúng) và thay đổi hàm curent_user = (user) thành hàm get_current_user đơn giản để xác định xem người dùng hiện tại có tồn tại không trong cookie.

Các thay đổi mã cuối cùng như sau:

#app/helpers/sessions_helper.rb 

    def sign_in(user) 
    cookies.permanent.signed[:remember_token] = [user.id, user.salt] 
    @current_user = user 
    end 

    def sign_out 
    cookies.delete(:remember_token) 
    @current_user = nil 
    end 

    def get_current_user 
    @current_user ||= user_from_remember_token 
    end 

    def signed_in? 
    !get_current_user.nil? 
    end 

#app/views/layouts/_header.erb 
<% if signed_in? %> 
       <li><%= link_to "Profile", get_current_user %></li> 
       <li><%= link_to "Sign out", signout_path, :method => :delete %></li> 
      <% else %> 
       <li><%= link_to "Sign in", signin_path %></li> 
      <% end %> 

Như bạn có thể thấy các biến trong phần đầu của tôi một phần cũng đã được thay đổi để phản ánh các phương pháp được sử dụng trong các helper để có được những người sử dụng.

Đi để bắt đầu đọc một số cơ bản của Ruby hướng dẫn thời gian để hôm sau tôi nhận được trong trên đầu của tôi Tôi có một ý tưởng về nơi để bắt đầu sửa chữa nó :)

+1

Cách thực hành tốt nhất để ủy quyền Rails là đặt tên cho phương thức current_user thay vì get_current_user và định nghĩa một phương thức current_user? kiểm tra xem current_user có phải là không. Đó là một mô hình rất phổ biến. –

+0

Có lý do cụ thể nào không? Hoặc là nó, giống như hầu hết mọi thứ của Rails dường như, chỉ vì đó là cách mọi người làm điều đó? Tôi có thể thấy sự gia tăng của khả năng đọc, chỉ cần tự hỏi nếu có một lý do khác mà tôi đang thiếu. – djlumley

+0

Nó không chỉ là một điều Rails. Quy ước Ruby cho getters và setters là attribute_name() và attribute_name =(). Khả năng thêm? để tên phương thức là cố ý để các nhà phát triển có thể hình thành các câu hỏi mạch lạc. Ruby được thiết kế để có tính tương tác nhất có thể. –

4

Hãy chắc chắn rằng bạn có mã sau trong SessionHelper

def current_user=(user) 
    @current_user = user 
end 

def current_user 
    @current_user ||= user_from_remember_token 
end 
Các vấn đề liên quan