Перенаправление Rails с новым действием

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

очень новое для rails. Я следил за книгой, которая очень помогает, но этого я не могу понять:

У меня есть методы контроллера с некоторыми действиями (методами) в нем:

 def patadas
    @technique = Category.find(4).technique
end

def golpes
    @technique = Category.find(3).technique
    respond_to do |format|      
        format.html { redirect_to(patadas_path) } 
    end
end
  

Идея состоит в том, чтобы иметь единую страницу, на которую я могу отправлять разные методы, и она будет их отображать. На странице patadas.html.erb есть это:

[ немного html]

 <% if @technique then %>
        <% @technique.each do |p| %>
            (<%= p.order %>) <%= p.korean %> - <%= p.spanish %><br />
        <% end %>
    <% else %>
        No techniques specified to show!    
    <% end %>
  

Моя проблема с перенаправлением. Я хочу иметь возможность отправлять разные методы на ту же страницу (очевидно, мне пришлось бы переименовать ее в techniques или что-то другое, кроме patadas) и заставить ее отображать технику, соответствующую вызываемому методу. Прямо сейчас выполняется перенаправление, но оно всегда показывает метод patadas.

О, у меня есть это в файле routes.rb:

 match '/patadas' => 'techniques#patadas', :as => 'patadas'
match '/golpes' => 'techniques#golpes', :as => 'golpes'
  

Все учебные пособия, книги и т. Д., Которые я видел, объясняют, как это сделать для одного представления для каждого действия, но это действительно расточительно, я хочу одно представление для всех этих разных действий. С помощью приведенных выше маршрутов я понимаю, что если я создам другое представление с именем ‘golpes.html.erb’, оно будет отображать их, но я ищу одно представление с разными действиями.

Спасибо.

PS Кроме того, возможно ли иметь что-то подобное:

 @frontal.each { |p| puts "(#{p.order}) #{p.korean} = #{p.spanish}" }
  

в файле представления (html.erb)? Это намного элегантнее, чем описанное выше безумие открытия и закрытия тегов <%= %> . Учитывая красоту Ruby, использование такого синтаксиса кажется расточительным. Я уверен, что должно быть, но я еще не продвинулся настолько 🙂

Редактировать: ввиду всех изменений, которые я внес (создал строительные леса для категории), я переписываю вопрос, чтобы прояснить ситуацию. Итак, теперь это то, что у меня есть:

categories_controller.rb

 [ bunch of stuff ]

def show
    @category = Category.find(params[:id])
  end
  

routes.rb

 resources :categories
  

В файле show я хотел бы перечислить все категории по идентификатору, чтобы
файл /categories/show.html.erb:

 I want to get category.order, category.category, category.spanish to show here
<%= link_to 'Edit', edit_category_path(@category) %> |
<%= link_to 'Back', categories_path %>
  

Пожалуйста, извините за мой идиотизм, но я не могу понять, что поместить в этот файл, чтобы отобразить содержимое. Если я попытаюсь сделать что-то вроде:

 <% @category.each do |cat| %>
    <li><%= cat.category %> - <%= cat.spanish %></li>           
<% end %>
  

Я получаю сообщение об ошибке

 undefined method `each' for #<Category:0x007f81c42a3fd0>
  

(Первоначальный вопрос был связан с маршрутами, я ошибочно хотел, чтобы маршруты обрабатывали разные действия, что на самом деле делается с помощью шаблона show, отсюда и ответ jimworm. Я отредактировал вопрос для ясности, так как я изменил так много вещей, но не могу вспомнить оригинальную формулировку, извините)

Комментарии:

1. Arghh, это так расстраивает. Я могу заставить index.htm.erb работать, потому что, конечно, там есть экземпляр @categories . Но страница показа не знает о методе techniques или контроллере, поэтому я не могу заставить это работать. Я думаю, что я слишком долго смотрел на это…

2. Хорошо, перечитав ваш пост в 20-й раз, я придумал это: <% @techniquesList.each do |tec| %> <%= tec.korean %> <br /> <% end %> И в классе Category: def show # @category = Category.find(params[:id]) @techniquesList = Category.find(params[:id]).technique Это (в основном) работает

3. Ваши модели / отношения неверны. Есть ли у категории один метод или несколько методов? Также: пожалуйста, верните свой первоначальный вопрос; в противном случае ничто в этом сообщении не имеет смысла.

4. Да, категория имеет несколько методов, почему вы говорите, что это неправильно? Извините, я не помню первоначальный вопрос, но я попытался прояснить ситуацию выше.

5. Кроме того, у меня проблема с некоторыми категориями, которые имеют подкатегорию (в той же таблице). Видите ли, некоторые категории имеют несколько методов, а другие имеют подкатегорию с несколькими методами. Я решаю это в Sql, проверяя, имеет ли категория pId (родительский идентификатор), если это так, я вызываю методы для нее напрямую, но использую ее родительское имя для полного имени. Но понятия не имею, как решить это с помощью Rails.

Ответ №1:

Добро пожаловать на путь Rails, пожалуйста, спрашивайте больше, если вы все еще застряли.

Перенаправления — это перенаправления, информация между запросами не сохраняется. Похоже, вы пытаетесь перечислить методы для каждой категории? Имейте в виду, что единственный вход, который у вас есть, — это категория, не имеющая ничего общего с методами. В этом случае я бы рекомендовал вложенный маршрут.

 # config/routes.rb
# this gives you the route /categories/:category_id/techniques, among other things
resources :categories do
  member do
    resources :techniques
  end
end

# app/controllers/techniques_controller.rb
# note that this is only called from inside the nested route
# so params[:category_id] is available
class TechniquesController < ActionController::Base
  def index
    @category = Category.find params[:category_id]
    @techniques = @category.techniques
  end
end

# app/views/techniques/show.html.erb
<% @techniques.each do |technique| %>
  <p>(<%= technique.order -%>) <%= technique.korean -%> - <%= technique.spanish -%></p>
<% end %>
  

Обратите внимание на использование params[:category_id] вместо фиксированных имен маршрутов. Вы всегда можете использовать friendly_id для поиска категорий с помощью slug вместо целого числа.

https://github.com/norman/friendly_id

Редактировать: обращение к вашему комментарию по одному пункту за раз (но не в правильном порядке):

В соглашении Rails есть большая разница между technique и techniques . Опытный рубист никогда бы не назвал список методов technique , потому что это просто сбивает с толку! Экземпляр Technique должен быть, так сказать, методом, и если в каждом экземпляре этой модели более одного метода, вы бы назвали его TechniqueList или TechniqueGroup или что-то в этом роде.

Вы просите, чтобы список методов отображался в show действии категории. В этом случае вам не понадобится вложенный маршрут. Вы можете использовать тот же метод для отображения списка категорий для определенного метода (при условии, что у вас есть отношение «многие ко многим» между категориями и методами).

 # app/controllers/categories_controller.rb
class CategoriesController < ActionController::Base
  def show
    # `includes` joins the techniques table, avoids n 1 lookups
    @category = Category.includes(:techniques).find params[:id]
  end
end

# app/views/categories/show.html.erb
<% @category.techniques.each do |technique| %>
  <p>(<%= technique.order -%>) <%= technique.korean -%> - <%= technique.spanish -%></p>
<% end %>
  

Подкатегории: что это такое? Модель? Запрос к Category модели? Я собираюсь обработать это как запрос в приведенном ниже коде.

 # app/models/category.rb
class Category < ActiveRecord::Base
  class << self # this adds class methods
    def sub_category_query(param)
      # this line is an example only, it depends on your query
      where(:sub_category => param)
    end
  end
end

# app/controllers/categories_controller.rb
class CategoriesController < ActionController::Base
  def sub_category
    @categories = Category.sub_category_query params[:sub_category]
    # since it's just showing a list of categories
    # you can probably reuse the index template here
    render :index
  end
end

# config/routes.rb
resources :categories do
  collection do
    # this give you an extra route to search by sub-category
    # rails guesses the action name, and expects a param here
    get 'sub_category/:sub_category'
  end
end
  

Комментарии:

1. Спасибо за ответ, я собираюсь попробовать это, но просто чтобы уточнить, я хотел бы использовать следующие маршруты: /categories/:category_id иметь методы для этой категории. Затем /techniques/:technique_id , чтобы иметь список этих методов. Затем /categories будет перечислен список всех категорий. Мне бы не хватило маршрута для перечисления подкатегорий… Как тогда будут выглядеть маршруты?

2. Обновил ответ с помощью более стандартного соглашения Rails. Надеюсь, вы найдете свой путь!

3. В надежде лучше понять это, я создал каркас для категорий, так что теперь у меня есть в CategoriesController: def show @category = Category.find(params[:id]) end В /categories/show.htm.erb: <% @category.each do |cat| %> <p>(<%= cat.order -%>) <%= cat.korean -%> - <%= cat.spanish -%></p> <% end %> <%= link_to 'Edit', edit_category_path(@category) %> | <%= link_to 'Back', categories_path %> Но я получаю сообщение об ошибке: undefined method каждый ‘ для #<Категория: 0x007f81c447bc18>` Как ни странно, последние 2 строки работают, но они не показывают ничего, кроме ссылок.

4. show Действие подразумевает, что отображается только один объект. .each используется для коллекции — массива объектов — поэтому он не будет работать с одним экземпляром Category . Сгенерировал ли эшафот этот неработающий код для вас? Если да, то какую версию Rails вы используете?

5. В Rails, если вы работаете .each с чем-то, что не является множественным числом, вы, вероятно, делаете это неправильно.