1

Я пытаюсь отфильтровать результаты по возрасту с помощью ransack, но ransack дает мне неопределенную ошибку метода. У меня есть DOB пользователей в моей базе данных, а в модели моих пользователей у меня есть возрастный метод, который вычисляет возраст пользователя. Он отлично работает, и я могу назвать пользователей возраст, как это:Неопределенная ошибка метода для фильтрации по возрасту с использованием Ransack gem

@user = User.find(1) 
@user.age 

Теперь рыскать я следующий в моем контроллере:

def index 
    @search = User.search(params[:q]) 
    @users = @search.result 
    end 

На мой взгляд, у меня есть:

<%= search_form_for @search do |f| %> 
    <%= f.label :age_gteq, "Ages:" %> <%= f.text_field :age_gteq %> 
    <%= f.label :age_lteq, "to" %> <%= f.text_field :age_lteq %> 
    <%=f.submit "Filter", class: "button" %> 
<% end %> 

Это ошибка я получаю:

undefined method `age_gteq' for Ransack::Search<class: User, base: Grouping <combinator: and>>:Ransack::Search 

Уверен, что у меня будет такая же ошибка для age_lteq

+0

Вы добавили 'age' в' attr_accessible'? – Zippie

+0

Нет, я этого не делал. Я не был уверен, что должен был, поскольку это метод, а не атрибут пользователя, хранящийся в базе данных. – pratski

+0

извините, но не возраст, а 'age_gteq' и' are_lteq'. Я не уверен, как использовать ransack, но это должно быть подсказка – Zippie

ответ

3

Насколько я знаю, это не сработает, потому что в настоящее время Ransack работает только с столбцами базы данных. В конечном итоге Ransack представляет собой просто сложный генератор запросов SQL.

Подумайте об этом, например:

User.where('age >= ?', 30) 

Что бы SQL-запрос выглядеть?

SELECT * FROM user WHERE age >= 30 

Даже если Ransack будет проходить через такие условия при нормальных атрибутах без базы данных, SQL все равно будет ошибочным. (Поскольку нет колонки age)

Одним из решений было бы использовать исходный стол для даты рождения в вашей форме и использовать некоторый Javascript, чтобы позволить пользователю вводить возрастные числа вместо дат. Например, прослушав событие onsubmit и изменив содержимое input.

Update 2014-01-08:

Существует еще одна возможность сделать эту работу. Добавьте это в User модели:

ransacker :age do 
    Arel::Nodes::SqlLiteral.new(
    'DATE_PART('year', AGE(NOW(), date_of_birth_column))') 
    # Beware: PostgreSQL specific SQL! 
end 

«грабитель» A должен возвращать узел Arel, который позже будет прикреплен к узлам AREL порожденных рыскать.

Это позволяет использовать age_eq и все другие предикаты Ransack, так же как и обычный столбец базы данных.

Смежные вопросы