#ruby-on-rails #nomethoderror
#ruby-on-rails #nomethoderror
Вопрос:
Я создаю сайт в RoR и создал формы регистрации и входа пользователей. Все работает отлично. Дело в том, что я пошел создавать другой объект под названием games, который функционирует почти идентично пользователям, но когда я пытаюсь взаимодействовать с ним, я получаю ошибку. Я построил формы почти точно так же, и маршрутизация у меня совпадает.
Вот мой пользователь new.html.erb:
<!DOCTYPE html>
<html>
<body>
<% provide(:title, 'Sign up') %>
<h1 class="heading1" >Sign up</h1>
<br>
<div>
<%= form_for(@user, :html => { :class => 'form' }) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name %>
<br>
<%= f.label :email %>
<%= f.text_field :email %>
<br>
<%= f.label :username %>
<%= f.text_field :username %>
<br>
<%= f.label :password %>
<%= f.password_field :password %>
<br>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation %>
<br>
<br>
<%= f.submit "Create my account", class: "submit" %>
<% end %>
</div>
</div>
</body>
</html>
и мой пользовательский контроллер new и методы создания:
def create
@user = User.new(user_params)
if @user.save
sign_in @user
redirect_to @user
else
render 'new'
end
end
def new
@user =User.new
end
private
def user_params
params.require(:user).permit(:name, :email, :username, :password,
:password_confirmation)
end
end
и моя игра new.html.erb:
<!DOCTYPE html>
<html>
<body>
<h1 class="heading1" >Create Game</h1>
<br>
<div>
<%= form_for(@game, :html => { :class => 'form' }) do |i| %>
<%= i.label :title %>
<%= i.text_field :title %>
<br>
<br>
<%= i.submit "Create Game", class: "submit" %>
<% end %>
</div>
</div>
</body>
</html>
и мой игровой контроллер:
def create
@game = Game.new(game_params)
if @game.save
redirect_to root_url
else
render 'create'
end
end
def new
@game = Game.new
end
private
def game_params
params.require(:game).permit(:title)
end
end
и мой файл маршрутизации:
Rails.application.routes.draw do
resources :sessions, only: [:new, :create, :destroy]
resources :users
match '/new_game', to: 'games#new', via: 'get'
match '/signup', to: 'users#new', via: 'get'
match '/signin', to: 'sessions#new', via: 'get'
match '/signout', to: 'sessions#destroy', via: 'delete'
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'home#home'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
Страница ошибок сервера rails гласит:
NoMethodError in Games#new
Showing /Users/Karen/Desktop/BR2/app/views/games/new.html.erb where line #7 raised:
undefined method `games_path' for #<#<Class:0x007fbfd6bdb260>:0x007fbfd6bd8948>
Extracted source (around line #7):
4
5
6
7
8
9
10
<h1 class="heading1" >Create Game</h1>
<br>
<div>
<%= form_for(@game, :html => { :class => 'form' }) do |i| %>
<%= i.label :title %>
<%= i.text_field :title %>
<br>
Rails.root: /Users/Karen/Desktop/BR2
Application Trace | Framework Trace | Full Trace
app/views/games/new.html.erb:7:in `_app_views_games_new_html_erb___3427370169918602482_70230959128880'
Request
Parameters:
None
Я действительно ценю всю и любую помощь. если есть какая-либо дополнительная информация, которую я могу предоставить, пожалуйста, скажите об этом.
Спасибо
Комментарии:
1. Стандартный первый шаг после ошибок route helper — это пролистывать маршруты, чтобы увидеть, какие помощники вы действительно получаете из своей конфигурации маршрута.
Ответ №1:
Лучший вариант — добавить games
определенные маршруты RESTful в routes.rb
resources :games
и удалите match '/new_game', to: 'games#new', via: 'get'
маршрут.
Выполнение этого даст вам следующие маршруты Restful:
Prefix Verb URI Pattern Controller#Action
games GET /games(.:format) games#index
POST /games(.:format) games#create
new_game GET /games/new(.:format) games#new
edit_game GET /games/:id/edit(.:format) games#edit
game GET /games/:id(.:format) games#show
PATCH /games/:id(.:format) games#update
PUT /games/:id(.:format) games#update
DELETE /games/:id(.:format) games#destroy
Таким образом, после отправки формы ваше приложение будет перенаправлено на create
action ( games_path
) с помощью HTTP Post запроса.
В настоящее время вы только что определили единственный маршрут для games
ресурса, который направляет к new
действию с
match '/new_game', to: 'games#new', via: 'get'
Но нет никакого маршрута для create
действий, поэтому вы получаете ошибку, как undefined method 'games_path'
в форме
Если вы не хотите использовать RESTful routes( resources :games
), вам нужно будет определить маршрут как:
match '/games', as: 'games', to: 'games#create', via: 'post'
для create
действий.
Ответ №2:
Вы обнаружите, что когда вы делаете bundle exec rake routes
это в своей консоли, вы фактически не создали именованные маршруты для своих игровых путей.
Если вы используете match
и хотите назвать маршрут (чтобы у вас было что-то вроде games_path
доступного), вам нужно будет сделать это:
match `/games`, as: 'games', to: 'games#index', via: :get
Гораздо более простой способ — использовать ресурсы для большинства ваших маршрутов и просто использовать пути RESTFUL по умолчанию:
resources :games
# Now you have access to '/games/new', '/games/:id',
# '/games', etc, as well as names such as `games_path`.
# Check `bundle exec rake routes` for all of them.
Дополнительную информацию см. В разделе Маршрутизация Rails
Комментарии:
1. Большое вам спасибо. Я чувствую себя идиотом. Наверное, я просто забыл объявить его как ресурс. Еще раз спасибо за помощь.
2. Не стесняйтесь принять мой ответ, если вы нашли, что он решил вашу проблему 😉