这很奇怪。
我的app/views/videos/upload.html.erb
看起来像这样:
<div class="bootstrap-styles">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">Upload your Video</h3>
<p><i>Step 2 of 2 - TEST</i></p>
</div>
<div class="modal-body">
<div class="form">
<% binding.pry %>
<%= form_tag @upload_info[:url], :multipart => true do %>
<div>Step 2 of 2</div>
<%= hidden_field_tag :token, @upload_info[:token] %>
<%= file_field_tag :file, title: 'Choose video to upload' %>
<p class="uploader">
<button class="btn btn-success ladda-button" data-color="green" data-style="expand-left"><span class="ladda-label">Upload Video</span><span class="ladda-spinner"></span></button>
</p>
<% end %>
</div>
</div>
<div class="modal-footer">
</div>
</div>
相应的Videos#Upload
控制器如下所示:
def upload
authorize! :read, @family_tree
@video = Video.find(params[:video_id])
@upload_info = Video.token_form(@video, video_save_video_path(@family_tree, @video))
respond_to do |format|
format.html
format.js
end
end
每当执行此upload
操作时,我都会收到此错误:
NoMethodError - undefined method `[]' for nil:NilClass:
app/views/videos/upload.html.erb:9:in `_app_views_videos_upload_html_erb___1805626926918975871_70299844626480'
所以我打破了我可靠的binding.pry
,这就是它变得有趣/奇怪的地方:
[1] pry(#<#<Class:0x007fdfea1e34e0>>)> @upload_info
=> nil
[2] pry(#<#<Class:0x007fdfea1e34e0>>)> @video
=> #<Video id: 39, title: "Drones", description: "Down in drones", yt_video_id: nil, is_complete: nil, created_at: "2014-11-21 00:41:03", updated_at: "2014-11-21 00:41:03", reply_id: nil, circa: nil>
[3] pry(#<#<Class:0x007fdfea1e34e0>>)> @family_tree
=> #<FamilyTree id: 1, name: "'s Family Tree", user_id: 1, created_at: "2014-10-04 15:37:18", updated_at: "2014-10-04 15:37:18">
[4] pry(#<#<Class:0x007fdfea1e34e0>>)> Video.token_form(@video, video_save_video_path(@family_tree, @video))
=> {:url=>
"http://uploads.gdata.youtube.com/action/FormDataUpload/AIwbFASzqNJ1rg?nexturl=/videos/1/save_video.39",
:token=>
"AI-SOME-TOKEN-b9ftw"}
[5] pry(#<#<Class:0x007fdfea1e34e0>>)> video_save_video_path
ActionController::UrlGenerationError: No route matches {:action=>"save_video", :controller=>"videos", :family_tree_id=>"1"} missing required keys: [:video_id]
from /.rvm/gems/ruby-2.0.0-p353@myapp/gems/actionpack-4.1.6/lib/action_dispatch/journey/formatter.rb:39:in `generate'
[6] pry(#<#<Class:0x007fdfea1e34e0>>)> @upload_info
=> nil
[7] pry(#<#<Class:0x007fdfea1e34e0>>)> @upload_info[:url]
NoMethodError: undefined method `[]' for nil:NilClass
from (pry):8:in `_app_views_videos_upload_html_erb___1805626926918975871_70299841189460'
所以我的控制器中设置的@upload_info
返回nil
,但是赋值部分,即:
Video.token_form(@video, video_save_video_path(@family_tree, @video))
返回我在pry中期望的值。
修改1
正在我的Upload
控制器中调用Video#Create
操作,如下所示:
def create
authorize! :read, @family_tree
@video = Video.new(video_params)
respond_to do |format|
if @video.save
format.html { render action: 'upload' }
else
format.html { render action: 'new' }
format.json { render json: @video.errors, status: :unprocessable_entity }
end
end
end
我修改了upload
操作以包含调试器信息,我看到没有任何内容写入日志文件 - 这表明Video#Upload
操作没有被执行。
这是有道理的,因为我的Video#Create
进程的日志如下所示:
Started POST "/family_trees/1/videos" for 127.0.0.1 at 2014-11-21 00:01:11 -0500
Processing by VideosController#create as JS
Parameters: {"utf8"=>"✓", "video"=>{"title"=>"Hello There", "description"=>"Hello World", "circa"=>"", "user_ids"=>[""]}, "commit"=>"Add Video", "family_tree_id"=>"1"}
User Load (1.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
FamilyTree Load (0.9ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."user_id" = $1 LIMIT 1 [["user_id", 1]]
FamilyTree Load (2.8ms) SELECT "family_trees".* FROM "family_trees" WHERE "family_trees"."id" = $1 LIMIT 1 [["id", 1]]
(1.0ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL))) [["user_id", 1]]
Membership Load (1.6ms) SELECT "memberships".* FROM "memberships" WHERE "memberships"."user_id" = 1 AND "memberships"."family_tree_id" = 1
(2.2ms) BEGIN
SQL (3.0ms) INSERT INTO "videos" ("created_at", "description", "title", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", "2014-11-21 05:01:11.486342"], ["description", "Hello World"], ["title", "Hello There"], ["updated_at", "2014-11-21 05:01:11.486342"]]
(2.4ms) COMMIT
Rendered videos/upload.html.erb within layouts/application (3.3ms)
Completed 500 Internal Server Error in 42ms
NoMethodError - undefined method `[]' for nil:NilClass:
app/views/videos/upload.html.erb:10:in `_app_views_videos_upload_html_erb___1805626926918975871_70299789284400'
所以它似乎试图在不执行控制器动作的情况下渲染videos/upload
的视图。
如何让它执行操作,但只有在@video.save
工作后才能执行?
答案 0 :(得分:1)
render action: 'upload'
不会调用upload
控制器方法。它只会渲染上传视图。因此@upload_info没有更新。使用redirect_to
而不是render来首先执行控制器代码:
具体而言,将format.html { render action: 'upload' }
替换为redirect_to upload_video_path(@video, ...)