开发者

Rails Changing Polymorphic Type Of An Object

We have a parent model Vehicle that is inherited to make classes Car, Truck, SUV. In our form, we allow the user to edit the data for a bunch of Vehicles, and one of the attributes for each vehicle is a select menu for "type". The HTML attribute is named vehicle_type and updates the actual Polymorphic type attribute in the Vehicle Model:

  # Get/Set Type bc rails doesnt allow :type to be set in mass
  def vehicle_type
    self.type
  end
  def vehicle_type=(type)
    self.type = type
  end

The problem we're having is that when we call update_attributes on form data and the type of an existing vehicle has been changed, rails is calling the validation for the old class (not new type) which results in errors. What we need to do is when vehicle_type is changed, that the model is changed to 开发者_JAVA百科that new type as well.

Is there a way to do this?


Here is the update action (fleet has_many vehicles):

  # PUT /fleet/1
  # PUT /fleet/1.xml
  def update
    @fleet = Fleet.find(params[:id])

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

Here is Fleet:

class Fleet < ActiveRecord::Base
  has_many :vehicles, :dependent => :destroy, :order => 'position ASC'
  accepts_nested_attributes_for :vehicles,
    :reject_if => proc { |attrs| attrs['name'].blank? },
    :allow_destroy => true


You could use a factory method to create the right type of vehicle, then assign the attributes.

def Vehicle.factory(type)
   type.constantize.new
end


When you call @vehicle.save, you could add false as the first parameter to skip validation (@vehicle.save(false)). Another option is to use ActiveRecord::Base#update_attribute -- which skips validation.

So you could save your model without the type column changing, then add a @vehicle.update_attribute(:type, "Truck") in the same action. Two SQL queries, but may be necessary for your situation.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜