Cod*_*ose 7 ruby ruby-on-rails ruby-on-rails-4
我使用Rails 4并出现以下错误.
路由错误
没有路由匹配[POST]"/ logs/1/meal/13/edit
我正在传递form_for模型对象使用:meal并且编辑页面正确呈现.但是,Rails似乎没有检查用餐对象是否已经保存,因此它一直尝试将表单发送到#create操作并尝试发出POST请求,而不是将表单发送到更新操作并进行制作点击提交时的PUT请求.
如何让form_for识别我正在尝试更新现有对象并且需要PUT而不是POST?其他一切正常,我已经完成了所有的迁移工作.我对Rails很陌生,而且我几乎整天都在试图自己解决这个问题.请帮忙!
而且要注意的是,当我尝试将模型对象传递为@ meal.log而不是:meal时,Rails再也无法识别:calorie_estimate或:meal_description.将模型对象作为@ meal.log传递给我留下了no方法错误.
餐/ edit.html.erb
<h3> EDIT MEAL </h3>
<%= form_for(:meal) do |f| %>
<div id="meal-form">
<%= f.text_field :calorie_estimate, class: 'meal-form-fields', :placeholder => "Calorie Estimate" %>
<%= f.text_field :meal_description, class: 'meal-form-fields', :placeholder => "Food Description" %>
<div class="submit-form" style="width: 75px; height: 15px;">
<%= f.submit 'UPDATE', :class => 'submit-form-text' %>
</div>
</div>
<% end %>
Run Code Online (Sandbox Code Playgroud)
meals_controller.rb
class MealsController < ApplicationController
include MealsHelper
def create
@meal = Meal.new(meal_params)
@meal.log_id = params[:log_id]
@meal.save
redirect_to log_path(@meal.log)
end
def edit
@meal = Meal.find(params[:id])
end
def update
@meal = Meal.find(params[:id])
@meal.update(meal_params)
redirect_to log_path(@log)
end
def meal_params
params.require(:meal).permit(:calorie_estimate, :meal_description)
end
end
Run Code Online (Sandbox Code Playgroud)
可能的路线:
Prefix Verb URI Pattern Controller#Action
root GET / logs#index
log_meals GET /logs/:log_id/meals(.:format) meals#index
POST /logs/:log_id/meals(.:format) meals#create
new_log_meal GET /logs/:log_id/meals/new(.:format) meals#new
edit_log_meal GET /logs/:log_id/meals/:id/edit(.:format) meals#edit
log_meal GET /logs/:log_id/meals/:id(.:format) meals#show
PATCH /logs/:log_id/meals/:id(.:format) meals#update
PUT /logs/:log_id/meals/:id(.:format) meals#update
DELETE /logs/:log_id/meals/:id(.:format) meals#destroy
logs GET /logs(.:format) logs#index
POST /logs(.:format) logs#create
new_log GET /logs/new(.:format) logs#new
edit_log GET /logs/:id/edit(.:format) logs#edit
log GET /logs/:id(.:format) logs#show
PATCH /logs/:id(.:format) logs#update
PUT /logs/:id(.:format) logs#update
DELETE /logs/:id(.:format) logs#destroy
Run Code Online (Sandbox Code Playgroud)
的routes.rb
Rails.application.routes.draw do
root to: 'logs#index'
resources :logs do
resources :meals
end
end
Run Code Online (Sandbox Code Playgroud)
schema.rb
ActiveRecord::Schema.define(version: 20160128205351) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "logs", force: :cascade do |t|
t.string "entry_date"
t.integer "calorie_goal"
t.string "notes"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "meals", force: :cascade do |t|
t.integer "calorie_estimate"
t.string "meal_description"
t.integer "log_id"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Run Code Online (Sandbox Code Playgroud)
问题是您正在使用nested resources,因此您对于将哪个@objects传递给您感到困惑form_for。
#app/views/meals/edit.html.erb
<%= form_for [@log, @meal] do |f| %>
Run Code Online (Sandbox Code Playgroud)
就像您目前所拥有的那样,传递:meal是模棱两可的 -Rails无法识别将其提交发送到的路线/方法,因为它没有可用的数据。
如果要更新对象,则必须将适当的数据传递到表单,包括对象的id:
<%= form_for :meal, url: { controller: "meals", action: "update", id: "5" }, method: :put do |f| %>
Run Code Online (Sandbox Code Playgroud)
例如Rails是面向对象的,最好将实际对象传递给您的form_for:
<%= form_for @meal ...
Run Code Online (Sandbox Code Playgroud)
-
您遇到的问题是您有一个嵌套资源:
resources :logs do
resources :meals #-> url.com/logs/:log_id/meals/:id
end
Run Code Online (Sandbox Code Playgroud)
这意味着您需要同时将Log和Meal值传递给您的form:
#app/controllers/meals_controller.rb
class MealsController < ApplicationController
def edit
@log = Log.find params[:log_id]
@meal = Meal.find params[:id]
end
def update
@log = Log.find params[:log_id]
@meal = Meal.find params[:id]
@meal.update meal_params
end
end
#app/views/meals/edit.html.erb
<%= form_for [@log, @meal] do |f| %>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3436 次 |
| 最近记录: |