Próbując napisać proste wyszukiwanie za pomocą zakresu, jednak dostaję dziwną odpowiedź i zastanawiałem się, czy ktoś może wyjaśnić mój błąd.

  scope :sounds_like, -> (item) { where('title ILIKE ?', "#{ params[:sounds_like] }%")}

A mój kontroler wygląda

 def index
    @items = Item.sounds_like(params[:sounds_like])
 end

Pobieram następujący błąd podczas próby wyszukiwania z interfejsu API.

NameError (undefined local variable or method `params' for #<Class:0x00007ff553a054d8>):

Czy jest jakiś sposób przekazywania paramsów do modelu bez użycia paramsów przekazanych z formularza?

0
Benjamin 3 czerwiec 2018, 08:46

3 odpowiedzi

Najlepsza odpowiedź

Zgodnie z opisem podanym następującym kodem nie będzie działać:

scope :sounds_like, -> (item) { where('title ILIKE ?', "#{ params[:sounds_like] }%")}

Ponieważ paraps nie są dostępne w modelu.

Zmodyfikuj powyższy wpływ na coś wymienionego poniżej:

scope :sounds_like, -> (item) { where('title ILIKE ?', "%#{item}%") }

W wyżej wymienionym zakresie przedmiot będzie argumentem, który będziesz przechodzić z kontrolera.

1
Rohan 3 czerwiec 2018, 12:12

W modelach Rails nie są Request świadome - nie mają dostępu do params, obiektu żądania lub sesji.

Aby przejść parametry z kontrolera do modelu, którego przekazujesz je jako argumenty metody:

class Thing < ApplicationRecord

  def self.sounds_like(value)
    where('title ILIKE ?', "#{ value }%")
  end
end

# call it as:
Thing.sounds_like('foo')

{x0}} to tylko cukierni składniczy, który umożliwia zwięźle pisanie metod klasy. Więc powyższe zostaną napisane jako:

class Thing < ApplicationRecord
  scope :sounds_like, ->(value){ where('title ILIKE ?', "#{ value }%")}
end

Drugi argument do scope jest LAMBDA - która jest anonimową funkcją, która działa jak metoda:

irb(main):001:0> l = -> (v) { puts v }
=> #<Proc:0x007f81dca27d48@(irb):1 (lambda)>
irb(main):002:0> l.call("Hello World")
Hello World
=> nil

Parenki oznacza argumenty Lambda, tak jak przy definiowaniu metod:

irb(main):016:0> lamb = -> (a, b) { [a,b].join(" ") }
=> #<Proc:0x007f81dc983ec8@(irb):16 (lambda)>
irb(main):017:0> lamb.call("Hello", "World")
=> "Hello World"
3
max 3 czerwiec 2018, 13:11

Postępuj zgodnie z tym w swoim zakresie

scope :sounds_like, -> (item) { where('title ILIKE ?', "%#{item}%") }

Powinno działać.

Dalsze informacje o zakresie szynami Możesz zobaczyć to Artykuł

1
fool-dev 3 czerwiec 2018, 06:23