RoR:如何修改控制器只接受更新几个参数?

时间:2010-07-12 11:30:43

标签: ruby-on-rails ruby

以下是rails生成的代码:

def update
  @user = User.find(params[:id])

  respond_to do |format|
    if @user.update_attributes(params[:user])
      flash[:notice] = 'User was successfully updated.'
      format.html { redirect_to(@user) }
      format.xml  { head :ok }
    else
      format.html { render :action => "edit" }
      format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
    end
  end
end      

但我不希望用户更新整个用户,假设我的用户有fname,lname和gender,而不是从视图中删除性别,我想限制更新方法只接受fname和lname ,如果他/她想更新性别,我不会允许他/她这样做。如何限制用户这样做?谢谢。

4 个答案:

答案 0 :(得分:3)

或添加自定义@user.update_only()方法,这样可以更轻松地在不同的上下文中重复使用...

class User
  def update_only(attrs = {}, *limit_to)
    update_attributes(attrs.delete_if { |k,v| !limit_to.include?(k.to_sym) })
  end
end

然后按照

的方式做点什么
@user.update_only(params[:user], :fname, :lname)

答案 1 :(得分:2)

ActiveRecord中有两种方法可以派上用场,attr_protectedattr_accessible

你像这样使用它们:

class MyModel < ActiveRecord::Base
    attr_accessible :fname, :lname #Allow mass-assignment
    attr_protected :secret #Do not allow mass-assignment
end

model = MyModel.new(:fname => "Firstname", :lname => "Lastname", :secret => "haha")
puts model.fname # "Firstname"
puts model.lname # "Lastname"
puts model.secret = nil # Can not be set through mass-assignment
model.secret = "mysecret" # May only be assigned like this
puts model.secret # "mysecret"

但是,如果您只在一个地方需要此功能,那么Salil的解决方案也可以正常工作。

需要注意的一点是,您应该使用attr_acessint将可以批量分配的属性列入白名单,并使其他所有属性都受到保护。通过这样做,你会阻碍卑鄙的人更新他们不应该接触的数据。

有关详细信息,请参阅the docs

答案 2 :(得分:1)

使用update_attributes的哈希参数

@user = User.find(params[:id])
@user.update_attributes(:fname=>params[:user][:fname], :lname=>params[:user][:lname])

答案 3 :(得分:0)

param[:user] Hash:

可以delete不需要的属性
# ...
attributes = params[:user]
gender = attributes.delete :gender
raise SomeError unless gender.blank?
if @user.update_attributes(attributes)
  # ...
end
# ...

此代码从Hash中删除:gender并检查它是否已填写。如果是,则引发异常。当然,你可以发出一个很好的警告,或者默默地忽略性别被填补的事实。