2010-06-24 37 views
25

Tôi có một phần, _flash.html.hamlTin nhắn của Flash trong Partials (Rails 3)

- flash.each do |type, value| 
    .flash{ :class => type.to_s } 
    = value 

Mà tôi đang render từ một cái nhìn sử dụng

=render :partial => "flash"

nào phàn nàn rằng băm flash là nil/undefined. Tuy nhiên, khi tôi làm điều này:

=render :partial => "flash", :locals => {:flash => flash}

Nó hoạt động.

Tại sao phần không có quyền truy cập vào thông báo flash?

Trả lời

24

Trong các phiên bản trước của Rails (Rails 2), biến cục bộ mặc định sẽ tìm một biến mẫu có cùng tên với phần trong phần tử cha.

Đưa ra ví dụ của bạn vì một phần được đặt tên là _flash, nó sẽ tự động chuyển đèn flash biến thể hiện dưới dạng cục bộ thành một phần. Vì vậy, bạn sẽ có quyền truy cập vào nó. Hành vi này không được chấp nhận trong 2.3 và đã bị xóa trong Rails 3.0.

Điều này có nghĩa là bạn luôn phải chuyển rõ ràng tất cả các biến mẫu như locals, thậm chí flash, giống như bạn đã viết trong ví dụ sau.

<%= render :partial => "flash", :locals => {:flash => flash} %>

này không có gì để làm với flash mỗi nói, flash là một biến Ví dụ cũng giống như bất kỳ khác.

+2

Nhưng 'flash' không phải là biến mẫu trong chế độ xem gốc, đó là phương thức trên' ActionView :: Base', cơ bản giống với phương thức trợ giúp. Vì vậy, tại sao không 'flash' trong một phần cuộc gọi cùng một phương pháp? – John

+8

Đó là vì không gian tên bóng. Một phần được đặt tên là flash, do đó nó đặt tên biến flash trong một phần để ủy nhiệm cho flash ivar trong mẫu cha, bất kể flash có tồn tại hay không. Khi @tothemario trả lời, đặt tên nó là cái gì đó khác sẽ chặn không gian tên. – Cluster

+0

@Cluster, tôi nghĩ rằng bạn chỉ cần thổi tâm trí của tôi. Đôi khi tôi tự hỏi nếu Rails "majic" không phải là một chút quá huyền diệu cho riêng của nó tốt. – guiniveretoo

22

Vì phần của bạn được đặt tên là "_flash", bạn nên có đối tượng: local để chỉ định flash thay đổi bên trong một phần.

Thay đổi tên một phần của bạn và bạn sẽ có thể sử dụng đèn flash bên trong, ví dụ:

= render "show_flash_names" 
+1

Tôi đã sử dụng = hiển thị 'bố cục/flash_messages'. Tôi thích giải pháp của bạn tốt hơn là chuyển người dân địa phương một cách rõ ràng. (: locals => {: flash => flash} quá chi tiết - yuck) –

+2

+1 về điều này: chỉ cần không đặt tên là "flash" và bạn có thể truy cập đối tượng flash Rails như bạn mong đợi. –

+0

Đây là câu trả lời! – brad

4

này cũng sẽ đạt được kết quả mong muốn của bạn:

<%= render partial: "flash", object: flash %>

Đối tượng flash đang được được chuyển đến số admin/shared/flash một phần là flash, vì một phần được gọi là flash. Bạn sẽ có quyền truy cập vào đối tượng flash từ bên trong một phần như bạn mong đợi trong bất kỳ chế độ xem thông thường nào.

5

Mỗi phần được hiển thị trong ngữ cảnh chứa biến cục bộ ngầm định có tên là một phần (không bao gồm dấu gạch dưới hàng đầu). Vì vậy, một số _flash.html.haml một phần sẽ always có một địa chỉ flash trong đó đổ bóng ActionView::Base#flash. Nếu bạn không vượt qua một cuộc tranh cãi với một phần (hoặc thông qua :locals => {:flash => flash} hoặc :object => flash, giá trị của các địa phương chỉ đơn giản là nil.

Như đã đề cập, bạn có thể đổi tên một phần để tránh những xung đột tên, hoặc sử dụng các tiết hơn gọi tới số render.

Đây là một sự phản ứng khó chịu của Rails, theo ý kiến ​​của tôi và I'd like to see it changed.

+0

Đây là câu trả lời hoàn chỉnh nhất, cung cấp nguyên nhân và cách giải quyết có thể. Tôi cũng đánh giá cao những nỗ lực của mình trong việc loại bỏ "bất ngờ" khỏi "tính năng" này. –

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