我使用"rails generate scaffold project"创建了一个新的web应用程序。我过去已经在运行其他版本rails和ruby的Linux和Mac OSX上做过这件事,一切都很好,但这次我在Windows 7上工作。这是我的环境
C:Usersuser1Company>ruby -v
ruby 2.0.0p451 (2014-02-24) [x64-mingw32]
C:Usersuser1Company>rails -v
DL is deprecated, please use Fiddle
Rails 4.1.0
C:Usersuser1Company>
在运行scaffold命令后,我运行了rakedb:migrate,并成功创建了我的第一个项目。然后我可以编辑项目,但当我点击更新时,我会收到以下错误消息
ArgumentError (When assigning attributes, you must pass a hash as an argument.):
完整的服务器日志消息
Started PATCH "/projects/1" for 127.0.0.1 at 2014-04-29 05:16:33 -0700
Processing by projectsController#update as HTML
Parameters: {"utf8"=>"√", "authenticity_token"=>"gST6BUQNwOZQDYVj60DXLuFANv1JsM02YAIM+xYwt/M=", "commit"=>"Update project", "id"=>"1"}
project Load (0.0ms) SELECT "projects".* FROM "projects" WHERE "projects"."id"= ? LIMIT 1 [["id", 1]]
(1.0ms) begin transaction
(0.0ms) rollback transaction
Completed 500 Internal Server Error in 10ms
ArgumentError (When assigning attributes, you must pass a hash as an argument.):
app/controllers/projects_controller.rb:44:in `block in update'
app/controllers/projects_controller.rb:43:in `update'
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (2.0ms)
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
Rendered C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (104.0ms)
这是我的"更新"方法(由scaffold命令自动创建(
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
respond_to do |format|
if @project.update(project_params)
format.html { redirect_to @project, notice: 'Update Successful!' }
format.json { render :show, status: :ok, location: @project }
else
format.html { render :edit }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
我尝试删除"PATCH/"关键字,但没有成功。我用以下方法替换了整个方法(这对我的另一个应用程序有效,但这次在Windows上无效(
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
@project = Project.find(params[:id])
if @project.update_attributes(params[:project])
flash[:notice] = "Update Successful!"
end
respond_with(@project)
end
但这并没有什么区别。
我也尝试过(我通过浏览SO找到了这个(
# PUT /projects/1
# PUT /projects/1.json
def update
@project = Project.find(params[:id])
respond_to do |format|
if @project.update_attributes(params[:project])
format.html { redirect_to @project, notice: 'Update Successful!' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
但也没有成功
以下是其他工作方法(都是由"rails generate scaffold"命令自动生成的,它们都工作得很好(
# GET /projects
# GET /projects.json
def index
@projects = project.all
end
# GET /projects/1
# GET /projects/1.json
def show
end
# GET /projects/new
def new
@project = project.new
end
# GET /projects/1/edit
def edit
end
# POST /projects
# POST /projects.json
def create
@project = project.new(project_params)
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: 'Creation Successful!' }
format.json { render :show, status: :created, location: @project }
else
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
为什么"rails generate scaffold"命令在Windows上不起作用,而在Linux和Mac OSX上运行良好?
更新1
以下是由"rails generate scaffold"命令自动创建的其他方法
class ProjectsController < ApplicationController
before_action :set_project, only: [:show, :edit, :update, :destroy]
<other methods listed above : index, show, new, edit, create, update, and destroy>
private
# Use callbacks to share common setup or constraints between actions.
def set_project
@project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params[:project]
end
end
进行Kirti Thorat建议的更改后的工作代码
这就是对我有效的
# PATCH/PUT /projects/1
# PATCH/PUT /projects/1.json
def update
@project = Project.find(params[:id])
respond_to do |format|
if @project.update(project_params)
format.html { redirect_to @project, notice: 'Project was successfully updated.' }
format.json { render :show, status: :ok, location: @project }
else
format.html { render :edit }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
@project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:UnitMgtAddress)
end
您刚刚创建了一个没有任何其他字段的scaffold。因此,projects
表只有3个默认字段id
、created_at
和updated_at
。因为在你的update
行动中,当你这样做时:
if @project.update(project_params)
或
if @project.update_attributes(params[:project])
您会得到错误,因为update
和update_attributes
需要一个Hash
作为参数,而params[:project]
为零。查看服务器日志中的params
哈希
{"utf8"=>"√", "authenticity_token"=>"gST6BUQNwOZQDYVj60DXLuFANv1JsM02YAIM+xYwt/M=", "commit"=>"Update project", "id"=>"1"}
它没有密钥project
可能的解决方案
不添加新字段
如果您不打算在projects
表中添加任何新字段,那么进行update
操作是没有意义的,因为您将更新哪个字段?
添加新字段
您可以根据需要向projects
表中添加新字段,如name
、duration
等(通过创建迁移来添加新字段(。
之后,您只需要更新project_params
方法,如下所示:
def project_params
params.require(:project).permit(:name, :duration)
end