Virtual attributes on new models in Rails?
This certain part of my application takes cares of creation of Webshop model for store chains (like H&M) that has one. If the chain has a website that also is a webshop it creates one Webshop model.
If the website is not a webshop then it lets it be just at string in the Chain model.
PROBLEM: I'm doing this with a checkbox and virtual attributes. So when sending the a request to the chain controller a checkbox sets the value 'set_webshop'.
# Chain Model
class Chain
has_one :webshop, :dependent => :destroy
def set_webshop
self.webshop.url == self.website unless self.webshop.blank?
end
def set_webshop=(value)
if self.webshop.blank?
value == "1" ? self.create_webshop(:url => self.website) : nil
else
value == "1" ? nil : self.webshop.destroy
end
end
end
# Chain Controller
class ChainsController < ApplicationController
def create
@chain = Chain.new(params[:chain])
respond_to do |format|
if @chain.save
flash[:notice] = 'Chain was successfully created.'
format.html { redirect_to(@chain) }
format.xml { render :xml => @chain, :status => :created, :location => @chain }
else
format.html { render :action => "new" }
format.xml { render :xml => @chain.errors, :status => :unprocessable_entity }
end
end
end
def update
params[:chain][:brand_ids] ||= []
@chain = Chain.find(params[:id])
respond_to do |format|
if @chain.update_attributes(params[:chain])
flash[:notice] = 'Chain was successfully updated.'
format.html { redirect_to(@chain) }
format.js
else
format.html { render :action => "edit" }
end
end
end
end
It all works perfectly when updating a Chain model but when not when creating a new one? I can't figure out why?
Here are the POST and PUT requests.
# POST (Doesn't work - does not create a Webshop)
Processing ChainsController#create (for 127.0.0.1 at 2010-02-06 11:01:52) [POST]
Parameters: {"commit"=>"Create", "chain"=>{"name"=>"H&M", "set_webshop"=>"1", "website"=>"http://www.hm.com", "desc"=>"...", "email"=>"info@hm.com"}, "authenticity_token"=>"[HIDDEN]"}
# PUT (Works - does create a Webshop)
Processing ChainsController#update (for 127.0.0.1 at 2010-02-06 11:09:13) [PUT]
Parameters: { "commit"=>"Update", "chain"=> { "name" => "H&M", "set_webshop"=>"1", "website" => "http://www.hm.com", "desc" => "...", "email" => "info@hm.com"}, "authenticity_token"=>"[HIDDEN]", "id"=>"444-h-m"}
Is there a special way to handle virtual_attributes开发者_JAVA技巧 on new models in Rails?
It probably doesn't work because in this line
self.create_webshop(:url => self.website)
to create a webshop for the new chain you have no id of the chain yet (it hasn't been created at this moment), so there's no possibility to create an association.
Define an after_save callback and create a webshop there. To remember the value of the checkbox in the meantime, you can store in an attr_accessor
.
精彩评论