开发者

RoR: How to modify the controller to accept update several params only?

Here is the code generated by rails:

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

  respond_to do |format|
    if @user.update_attributes(params[:user])
      flash[:notice] = 'User was successful开发者_JAVA百科ly 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      

But I don't want user to update the whole user, assume that my user have fname, lname and gender, instead of remove the gender from the view, I want to restrict that the update method ONLY accept fname and lname only, if he/she want to update the gender, I won't allow him/her to do so. How can I restrict the user to do so? thank you.


or add a custom @user.update_only() method, which makes it also easier to reuse in different contexts...

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

Then just do something along the lines of

@user.update_only(params[:user], :fname, :lname)


There are two methods in ActiveRecord that come in handy in cases like these, attr_protected and attr_accessible.

You use them like this:

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"

However, if you only need this functionality at one place, then Salil's solution will work just as well.

One thing to note is that you should use attr_acessible to whitelist attributes that are OK to mass-assign, and make every other attribute protected. By doing so, you hinder mean people for updating data they are not supposed to touch.

See the docs for more info.


Use Hash parameters of the update_attributes

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


You can delete unwanted attributes from the param[:user] Hash:

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

This code removes :gender from the Hash and checks if it is filled in. If so, an exception is raised. Of course you could give a nice warning or silently ignore the fact that the gender was filled in.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜