#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
с чем-то, что не является множественным числом, вы, вероятно, делаете это неправильно.