2011-08-17 42 views
5

Tôi gặp lỗi từ một trong các lớp điều khiển của mình và tôi không thể hiểu tại sao. Lỗi này là:

SyntaxError in TermsController#show, syntax error, unexpected $end, expecting keyword_end 

Đây là terms_controller.rb:

class TermsController < ApplicationController 

    def show 
     @term = Term.find(params[:id]) 
     if @term.id == 1 
      @title = "Fall" 
     else if @term.id == 2 
      @title = "Winter" 
     else if @term.id == 3 
      @title = "Spring" 
     else if @term.id == 4 
      @title = "Summer" 
     end 
    end 
end 

trang chương trình của tôi hiện chỉ bao gồm:

<h1> <%= @title %> </h1> 

Đây có thể là một cái gì đó nhỏ mà tôi chỉ thiếu - Cảm ơn bạn đã giúp đỡ!

Trả lời

10

Các vấn đề mà không có đủ end từ khóa và nó tìm thấy $end (token đại diện cho cuối của tập tin) trước khi nó có thể tìm thấy những gì nó đang tìm kiếm - end khác. (Các dấu hiệu phân tích cú pháp cho từ khóa end là một trong hai "keyword_end" hoặc "Kend", tùy thuộc vào phiên bản ruby.)

Mỗi biểuif đòi hỏi một end từ khóa phù hợp.

Để giải quyết vấn đề này, hãy sử dụng elsif thay vì else if. Nó là một phần của cùng một cấu trúc if và không yêu cầu kết hợp end (chỉ if yêu cầu kết hợp end).

if x == 1 
    "1" 
    elsif x == 2 
    "2" 
    else 
    "else"   
    end 

lựa chọn khác là case mà hoạt động tốt nếu tất cả các chi nhánh kiểm tra toán hạng cùng có điều kiện (x trong trường hợp này):

case x 
    when 1 then "1" 
    when 2 then "2" 
    else "else" 
    end 

Nếu bạn làm muốn sử dụng else if (hãy nhớ, mỗi if bắt đầu một cấu trúc có điều kiện mới if) sau đó đảm bảo đóng mỗi khối mà mở ra if. Tôi đã thụt lề mã để hiển thị điểm này tốt hơn.

if x == 1 
    "1" 
    else 
    if x == 2 
     "2" 
    else 
     "else" 
    end 
    end 

Mã hóa vui vẻ.


Đối với pedantic: đó cũng là một hình thức if, đó là expr if cond, mà không có một phù hợp với end như một phần của cú pháp và các quy tắc đề cập ở trên không áp dụng đối với nó.

Bên cạnh đó, ifcasechỉ biểu thức trong Ruby, vì vậy nó có thể được idiomatically hơn bằng văn bản như thế này

@term = Term.find(params[:id]) 
@title = case @term.id 
    when 1 then "Fall" 
    when 2 then "Winter" 
    when 3 then "Spring" 
    when 4 then "Summer" 
    else "Invalid Term" 
end 

Cú pháp if/elsif/end thể được sử dụng trong cùng một cách, nhưng sử dụng case tránh được nhắc lại nhiều lần @term.id.Một tùy chọn khác là sử dụng một Hash để thực hiện loại ánh xạ đơn giản này - hoặc ánh xạ có thể được đóng gói theo một phương pháp riêng biệt - nhưng được bao phủ ở nơi khác ;-)

1

Thay vì else if sử dụng elsif.

1

Tại sao không chỉ làm điều này:

class TermsController < ApplicationController 

    @@seasons = { 1 => "Fall", 2 => "Winter", 3 => "Spring", 4 => "Summer"} 

    def show 
    @term = Term.find(params[:id]) 
    @title = @@seasons[params[:id]] || "Invalid Season" 
    end 

end 
+0

Trong xem xét mã ban đầu của bạn, bạn thực sự đang sử dụng các điều khoản id để có được mùa giải. Nó có thể là tốt nhất để ghi đè lên các thuộc tính tiêu đề accessor trong lớp Term để trả về String đúng .. có thể sử dụng băm và tra cứu như tôi có ở đây trong bộ điều khiển trong mô hình. –

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