Phát triển hình thức trong một bộ điều khiển khác


128

Tôi đang sử dụng một viên ngọc phát minh cho các thủ tục đăng nhập / đăng nhập.

Tôi đã tạo các tệp xem từ phát minh, sử dụng rails g devise views

Tôi thấy có một tệp devise / session / new.html.erb có chứa một biểu mẫu cho Sign_in.

Tôi đã tạo một tệp khác devise / session / _form.html.erb và đã làm <%= render 'form' %>trong một tệp new.html.erb và điều đó đã hoạt động rất tốt.

Bây giờ, tôi muốn bao gồm biểu mẫu này từ bộ điều khiển khác nhau. Vì vậy, trong một bộ điều khiển có tên 'chính', (cụ thể, trong trang xem) 'tệp chính / index.html.erb' tôi đã bao gồm <%= render 'devise/sessions/form' %>. Có vẻ như bao gồm hoạt động tốt, nhưng tôi nhận được lỗi sau.

NameError in Mains#index

Showing /home/administrator/Ruby/site_v4_ruby/app/views/devise/sessions/_form.html.erb where line #1 raised:

undefined local variable or method `resource' for #<#<Class:0x007f1aa042d530>:0x007f1aa042b870>
Extracted source (around line #1):

1: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
2:   <p><%= f.label :email %><br />
3:   <%= f.text_field :email %></p>
4: 

Có vẻ như phần form_for (resource, ...) đang gây ra sự cố (hoạt động tốt nếu tôi ở trang đăng nhập dev_in ban đầu ... Làm cách nào tôi có thể giải quyết vấn đề này theo cách rails?

Cá nhân tôi thích sử dụng chức năng 'kết xuất' để bao gồm biểu mẫu, thay vì viết mã html nội tuyến.

Tôi có phải chỉ định một cái gì đó (tài nguyên) trong bộ điều khiển 'chính' không?

Tôi sẽ đánh giá cao sự giúp đỡ của bạn. Cảm ơn bạn.


Có giải pháp nào không ...? Kể từ ngày 16 tháng 11, tôi chưa thực sự có giải pháp bằng cách sử dụng kết xuất .. mặc dù nếu tôi chỉ nhập mã nội tuyến, nó có vẻ hoạt động tốt ..
user482594

bạn đã tìm ra giải pháp cho việc này chưa?
neebz

Có, tôi đã chọn câu trả lời giải quyết vấn đề của mình. Nó đơn giản hơn tôi nghĩ.
dùng482594

Câu trả lời:


240

Như Andres nói, biểu mẫu gọi các trình trợ giúp được chỉ định bởi Devise và do đó không có mặt khi bạn truy cập vào biểu mẫu Devise từ bộ điều khiển không Devise.

Để giải quyết vấn đề này, bạn cần thêm các phương thức sau vào lớp trình trợ giúp của bộ điều khiển mà bạn muốn hiển thị biểu mẫu bên dưới. Ngoài ra, bạn chỉ có thể thêm chúng vào trình trợ giúp ứng dụng của mình để làm cho chúng có sẵn ở bất cứ đâu.

  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end

Nguồn: http://pupeno.com/blog/show-a-devise-log-in-form-in-another-page/


6
Thông minh. Hãy chắc chắn rằng nó đi trong trình trợ giúp, không phải trong bộ điều khiển. Ngoài ra, điều này có thể dẫn đến các vấn đề lớn nếu bạn có các tài nguyên khác (ví dụ: các công ty cũng có thể đăng nhập) và bạn muốn tải biểu mẫu của họ. Đảm bảo xác định lại tên và định tuyến cũng có thể trở thành vấn đề.
Michael Schmitz

1
Điều tồi tệ về giải pháp này là nó bị hỏng inherited_resources.
jrhorn424

6
Để giới hạn phạm vi của các phương thức này (và tránh xung đột không gian tên với các loại đá quý khác), hãy thử thêm các phương thức trên vào chính bộ điều khiển, cùng với helper_method :resource_name, :resource_class, :resource, :devise_mapping( :resource_classdường như là một yêu cầu trong các phiên bản Devise mới hơn).
spume

1
Giải pháp nào nên có nếu chúng ta có ít mô hình nghĩ ra?
yozzz

Tôi có hai mô hình Devise và cần đăng nhập cho cả hai trên trang chủ. Bất kỳ ý tưởng làm thế nào để làm một cái gì đó tương tự như câu trả lời của bạn?
DR_

8

Có thể thử điều này cũng ... kiểm tra câu hỏi này .

Nguồn

<%= form_for("user", :url => user_session_path) do |f| %>
  <%= f.text_field :email %>
  <%= f.password_field :password %>
  <%= f.check_box :remember_me %>
  <%= f.label :remember_me %>
  <%= f.submit 'Sign in' %>
  <%= link_to "Forgot your password?", new_password_path('user') %>
<% end %> 

Đây không phải là cách thực hành tốt nhất trong tất cả các câu trả lời sao?
allegutta

4

Biểu mẫu bạn đã tạo hoạt động khi được hiển thị từ bộ điều khiển Devise vì "tài nguyên" được xác định thông qua Devise. Hãy xem việc triển khai Devise SessionsContoder - từ những gì tôi hiểu, bạn đang cố gắng sao chép hành động "mới". Phương thức "build_resource" có lẽ là thứ bạn đang chăm sóc.

Viên ngọc Warden là nơi các đối tượng "tài nguyên" đến từ. Nếu bạn muốn đào sâu hơn, đó sẽ là nơi để tìm kiếm.


Tôi vừa gọi 'build_resource' với trong một mains_controll, nhưng nó gọi ra lỗi [biến cục bộ hoặc phương thức `build_resource '] không xác định. Tôi đã thử bao gồm phát minh trình trợ giúp nội bộ bằng cách chèn 'bao gồm Devise :: Bộ điều khiển :: Bộ trợ giúp nội bộ' ở đầu 'mains_controll' nhưng nó cũng gọi ra lỗi với 'AbstractContoder :: ActionNotFound'
user482594

3

Để tinh chỉnh câu trả lời được chấp nhận, chúng tôi sử dụng trợ giúp này để cho phép các loại tài nguyên khác nhau:

def resource_name
  @resource_name ||= if admin_controller?
    :admin_user
  else
    :user
  end
end

def resource
  @resource ||= resource_name.to_s.classify.constantize.new
end

def devise_mapping
  @devise_mapping ||= Devise.mappings[resource_name]
end

nơi admin_controller?là một cái gì đó chúng tôi có từ trước trong ApplicationControllerđể đổi hướng xử lý đăng nhập:

def admin_controller?
  !devise_controller? and request.path =~ /^\/admin/
end
helper_method :admin_controller?

2

Tôi đã nhận được cùng một lỗi undefined local variable or method "resource"mà bạn mô tả từ một trong các bộ điều khiển của mình, vì lớp cơ sở của bộ điều khiển của tôi bị thiếu như sau (Rails-API ActionContoder :: API bị lỗi):

include ActionController::Helpers

Do đó, các phương thức trợ giúp từ Devise không thể được giải quyết trong chế độ xem.

Để làm cho Devise hoạt động với Rails-API tôi cần bao gồm:

class ApplicationController < ActionController::API

  include AbstractController::Rendering
  include AbstractController::Layouts
  include ActionController::MimeResponds
  include AbstractController::Translation
  include ActionController::ImplicitRender
  include ActionController::Helpers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.