我正在尝试为简单的Rails 4.1待办事项列表应用程序设置编辑/更新操作。 具体来说,我希望能够编辑和更新与“用户”资源相关联并嵌套的资源“项目”。目前我收到以下错误。
分配属性时,必须将哈希作为参数传递。
respond_to do |format|
if @project.update_attributes(params[:project]) -------> error is in this line
format.html { redirect_to([@project.user, @project], :notice => 'project was successfully updated.') }
format.xml { head :ok }
这是我的代码: 路线:
Rails.application.routes.draw do
resources :users
resources :users do
resources :projects
end
root 'welcome#index'
end
Users_controller:
class UsersController < ApplicationController
def index
@users=User.all
end
def new
@user= User.new
end
def create
@user = User.new(user_params)
@user.save
redirect_to @user
end
def show
@user=User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to @user
else
render 'edit'
end
end
#edit is related to the route patch
def edit
@user = User.find(params[:id])
end
def destroy
@user = User.find(params[:id])
@user.destroy
redirect_to users_path
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
projects_controller:
class ProjectsController < ApplicationController
def create
@user = User.find(params[:user_id])
@project = @user.projects.create(project_params)
redirect_to user_path(@user)
end
def destroy
@user = User.find(params[:user_id])
@project = @user.projects.find(params[:id])
@project.destroy
redirect_to user_path(@user)
end
def update
@user = User.find(params[:user_id])
@project = @user.projects.find(params[:id])
respond_to do |format|
if @project.update_attributes(params[:project])
#1st argument of redirect_to is an array, in order to build the correct route to the nested resource project
format.html { redirect_to([@project.user, @project], :notice => 'project was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @project.errors, :status => :unprocessable_entity }
end
end
end
def edit
@user = User.find(params[:id])
@project = @user.projects.find(params[:id])
end
private
def project_params
params.require(:project).permit(:project_name, :description)
end
end
用户模型:
class User < ActiveRecord::Base
has_many :projects
end
项目模型:
class Project < ActiveRecord::Base
belongs_to :user
end
非常感谢!
答案 0 :(得分:3)
对于初学者,您需要告诉您的父模型他将与嵌套的子模型(或更多)一起保存,例如:
class User < ActiveRecord::Base
has_many :projects
accepts_nested_attributes_for :projects
end
在Rails 4中,您可以通过白名单或允许您想要传递的参数:
#UsersController
def user_params
params.require(:user).permit([:id, :name, :email, projects_attributes: [:name,
:price] ]) #list all the attributes that you want to allow to be passed from the view to the model when in the controller
end
仍然在UsersController中,您需要传递已修改的参数,或 user_params 而不是参数。
def update
@user = User.find(user_params[:id])
if @user.update(user_params) #this will already save your nested project along with the user
redirect_to @user
else
render 'edit'
end
end
由于项目与UsersController中的用户一起保存,我的意思是,您不需要在ProjectsController中保存/更新项目,将其从用户中删除,然后将其保存回来。
答案 1 :(得分:0)
您的路线应为:
Rails.application.routes.draw do
resources :users do
resources :projects
end
root 'welcome#index'
end
另外,不要忘记将新属性列入白名单!