2010-07-12 21 views
0

下面是轨道生成的代码:RoR:如何修改控制器以仅接受更新几个参数?

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和性别,而不是从视图中删除性别,我想限制更新方法只接受fname和lname,如果他/她想更新性别,我不会允许他/她这样做。我如何限制用户这样做?谢谢。

+0

您确定要在控制器/模型级别使用此功能吗?根据我自己的经验,我会尝试使用JavaScript或使用多种形式(一种用于性别更新,一种用于名称更新,两种都使用相同/更新)来防止这种情况 - 特别是如果您希望提供可靠的XML API作为好。 “你不能同时改变你的名字和性别”在API文档中阅读真的很奇怪。 – 2010-07-12 12:01:41

回答

1

的update_attributes方法的使用哈希参数

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

对不起,我想知道,@@用户的意思是什么?为什么不只@用户。谢谢。 – Tattat 2010-07-12 11:40:35

+0

这是错误的,它应该像'@ user.update_attributes(...)',就像你在例子中使用的那样。 – Veger 2010-07-12 11:42:34

+0

@Tattat: - 这只是在这里输错了对不起。但如果我没有错'@@'变量被用来表示'轨道中的全局变量' – Salil 2010-07-12 11:44:21

0

可以从param[:user]哈希delete不需要的属性:

# ... 
attributes = params[:user] 
gender = attributes.delete :gender 
raise SomeError unless gender.blank? 
if @user.update_attributes(attributes) 
    # ... 
end 
# ... 

此代码将删除哈希并检查它是否填充:gender如果。所以会引发异常。当然,你可以提供一个很好的警告或自动忽略性别充满的事实。

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) 
+0

我必须说我喜欢这个想法。这将是对ActiveRecord的一个很好的扩展(或者可能是对update_attributes的一个很好的扩展,使用:也许除了hash)。 – 2010-07-12 11:55:29

+0

,它透明地处理attr_protected /访问以及 - 随意包装它作为插件,或将其添加到AR :: Base(将有意义) – lwe 2010-07-12 12:08:14

+0

好主意的一般解决方案 – bjg 2010-07-12 13:43:55

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" 

但是,如果你只需要在一个地方这个功能,那么萨里尔的解决方案将很好的工作。

需要注意的一件事是,您应该使用attr_acessible将可以批量分配的属性列入白名单,并且保护其他所有属性。通过这样做,您可以阻止有意的人更新他们不应该触摸的数据。

有关更多信息,请参阅the docs

+0

这是所有提供的最好的答案,没有黑客攻击并且在模型层面工作,这就是这种代码应该在哪里。 – Faisal 2010-07-12 14:31:47

相关问题