Rails - Cara menggunakan Helper Inside a Controller

207

sementara saya menyadari bahwa Anda seharusnya menggunakan helper di dalam view, saya membutuhkan helper di controller saya karena saya sedang membangun objek JSON untuk kembali.

Bunyinya sedikit seperti ini:

def xxxxx

   @comments = Array.new

   @c_comments.each do |comment|
   @comments << {
     :id => comment.id,
     :content => html_format(comment.content)
   }
   end

   render :json => @comments
end

bagaimana saya bisa mengakses html_formatpembantu saya ?

AnApprentice
sumber
2
Anda mungkin ingin mempertimbangkan jawaban @ grosser, jauh lebih lengkap.
tokland
Saya tahu ini sudah tua tapi ... apa yang salah dengan kelas ruby ​​biasa? : p
Tarek

Jawaban:

205

Catatan: Ini ditulis dan diterima kembali dalam Rails 2 hari; Saat ini jawaban Grosser adalah jalan yang harus ditempuh.

Opsi 1: Mungkin cara paling sederhana adalah dengan memasukkan modul helper Anda di controller Anda:

class MyController < ApplicationController
  include MyHelper

  def xxxx
    @comments = []
    Comment.find_each do |comment|
      @comments << {:id => comment.id, :html => html_format(comment.content)}
    end
  end
end

Opsi 2: Atau Anda dapat mendeklarasikan metode helper sebagai fungsi kelas, dan menggunakannya seperti:

MyHelper.html_format(comment.content)

Jika Anda ingin dapat menggunakannya sebagai fungsi instance dan fungsi kelas, Anda bisa mendeklarasikan kedua versi dalam helper Anda:

module MyHelper
  def self.html_format(str)
    process(str)
  end

  def html_format(str)
    MyHelper.html_format(str)
  end
end

Semoga ini membantu!

Xavier Holt
sumber
Terima kasih tapi saya agak bingung. Saat ini helper saya ada di /app/helpers/application_helper.rb ... Apakah Anda menyarankan agar saya memindahkan helper ke ApplicationController?
AnApprentice
Saya menambahkan 'sertakan ApplicationHelper' ke application_controller saya tetapi kesalahan dengan 'NoMethodError (metode yang tidak ditentukan `html_format' untuk ApplicationHelper: Module): '
AnApprentice
1
@AnApprentice Sepertinya Anda sudah mengetahuinya, tapi saya sedikit mengubah jawaban saya, semoga membuat semuanya lebih jelas. Di versi pertama, Anda bisa menggunakan html_format- Anda hanya perlu MyHelper.html_formatdi versi kedua.
Xavier Holt
4
Ini tidak berfungsi ketika metode pembantu yang ingin Anda gunakan memanfaatkan metode tampilan seperti link_to. Pengontrol tidak memiliki akses ke metode ini dan sebagian besar pembantu saya menggunakan metode ini. Juga, termasuk helper ke controller memperlihatkan semua metode helper sebagai tindakan yang dapat diakses publik yang tidak baik. view_contextadalah cara untuk masuk dalam Rails 3.
GregT
@RegT - Belum pernah melihat jawaban Grosser sebelumnya, karena datang sedikit setelah fakta, tapi saya juga lebih suka. Dia baru saja mendapat dukungan saya.
Xavier Holt
304

Kamu bisa memakai

  • helpers.<helper>dalam Rails 5+ (atau ActionController::Base.helpers.<helper>)
  • view_context.<helper>( Rails 4 & 3 ) (PERINGATAN: ini instantiates tampilan instance baru per panggilan)
  • @template.<helper>( Rel 2 )
  • termasuk penolong di kelas tunggal dan kemudian singleton.helper
  • include helper di controller (PERINGATAN: akan membuat semua metode helper menjadi aksi controller)
lebih kotor
sumber
56
Jawaban ini bahkan lebih baik! Di rel 3, cukup menelepon view_context.helper_functionitu sederhana dan berfungsi dengan baik. ActionController::Base.helpers.helper_functionsama baiknya.
trisweb
29
view_context= genius
n_i_c_k
5
PERINGATAN: Jangan gunakan view_context. Ini akan membuat instance tampilan baru per panggilan ...
fny
7
ActionController::Base.helpers.helper_functionsepertinya tidak berfungsi. Saya dapatkan NoMethodError - undefined method spell_date_and_time' for #<ActionView::Base:0x007fede56102d0>:ketika mencoba memanggil ActionController::Base.helpers.spell_date_and_time()metode pengontrol. panggilan view_context.spell_date_and_time()tidak berhasil.
Lele
37
rails 5: cukup gunakan helpers.helper_functiondi controller Anda ( github.com/rails/rails/pull/24866 )
Markus
80

Di Rails 5 gunakan helpers.helper_functiondi controller Anda.

Contoh:

def update
  # ...
  redirect_to root_url, notice: "Updated #{helpers.pluralize(count, 'record')}"
end

Sumber: Dari komentar oleh @ Markus pada jawaban yang berbeda. Saya merasa jawabannya pantas untuk dijawab sendiri karena merupakan solusi paling bersih dan mudah.

Referensi: https://github.com/rails/rails/pull/24866

Gerry Shaw
sumber
6
Terasa agak aneh bahwa di konsol Anda akan memanggil helpertunggal dan di controller itu jamak.
Fellow Stranger
10

Masalah saya diselesaikan dengan Opsi 1. Mungkin cara paling sederhana adalah dengan memasukkan modul pembantu Anda di controller Anda:

class ApplicationController < ActionController::Base
  include ApplicationHelper

...
Thadeu Esteves Jr.
sumber
1
Satunya downside yang menambahkan tindakan pengontrol dengan nama fungsi pembantu. Tapi tbh, aku juga melakukan itu :)
Felix
9

Secara umum, jika helper akan digunakan di (hanya) pengendali, saya lebih suka menyatakannya sebagai metode instance dari class ApplicationController.

Franco
sumber
5
Sebagai metode yang dilindungi
Benjamin Crouzier
3

Di Rails 5+ Anda cukup menggunakan fungsi seperti yang ditunjukkan di bawah ini dengan contoh sederhana:

module ApplicationHelper
  # format datetime in the format #2018-12-01 12:12 PM
  def datetime_format(datetime = nil)
    if datetime
      datetime.strftime('%Y-%m-%d %H:%M %p')
    else
      'NA'
    end
  end
end

class ExamplesController < ApplicationController
  def index
    current_datetime = helpers.datetime_format DateTime.now
    raise current_datetime.inspect
  end
end

KELUARAN

"2018-12-10 01:01 AM"
Ravistm
sumber
0
class MyController < ApplicationController
    # include your helper
    include MyHelper
    # or Rails helper
    include ActionView::Helpers::NumberHelper

    def my_action
      price = number_to_currency(10000)
    end
end

Di Rails 5+ cukup gunakan helper ( helpers.number_to_currency (10000) )

albertm
sumber