我有一个红宝石(在轨道上)类:
class User < ActiveRecord::Base
# relationships
belongs_to :current_shipping_address, :class_name => "Address"
belongs_to :subscription
# Validators
validates_presence_of :subscription
validates_presence_of :current_shipping_address
end
我在控制器中执行此操作:
subscription = Subscription.new
address_info = params[:user].delete(:address) rescue {}
@address = Address.new(address_info.merge(:country => "US"))
@user = User.new(params[:user].merge(:first_name => @address.first_name, :last_name => @address.last_name))
@user.subscription = subscription
@user.current_shipping_address = @address
@user.save!
此时,令人难以置信的是,我有一个@user已保存在数据库中但没有current_shipping_address(尽管有验证)。订阅也已保存在数据库中。
地址不会被保存。
我在这里缺少什么? 1 - 如果没有验证失败,用户如何保存? 2 - 为什么地址没有保存?
如何更改此代码以便保存地址(正如我所期望的那样)?
我在rails 3上的ruby下运行它。
谢谢!
答案 0 :(得分:0)
在您的情况下,用户无法保存订阅和current_shipping_address,因为它们不是模型用户中的简单字段。您通过belongs_to将它们定义为与User相关联的模型,我不确定您愿意做什么,但如果我理解正确,则使用嵌套属性:
class User < ActiveRecord::Base
# relationships
has_many :current_shipping_addresses, :class_name => "Address", :dependant => destroy
has_many :subscriptions, :dependant => destroy
# Nesting
accepts_nested_attributes_for :subscriptions
accepts_nested_attributes_for :current_shipping_addresses
end
之后,当您创建并保存用户时,会保存订阅和current_shipping_address。
有关此处关联的更多信息:http://guides.rubyonrails.org/association_basics.html
答案 1 :(得分:0)
如果您不遵守标准表结构,则需要告诉它外键是什么。你只需要添加:
belongs_to :current_shipping_address, :class_name => "Address", :foreign_key => "address_id"
或用于将地址ID存储到地址表的任何列。
这不是建议的嵌套属性的方法。我建议您在表单中使用fields_for
而不是使用以下行:
address_info = params[:user].delete(:address) rescue {}
@address = Address.new(address_info.merge(:country => "US"))
你可以做到
&lt;%= f.fields_for:current_shipping_address do | ff | %GT; #...您的地址字段...... &lt;%end%&gt;
然后您可以在运行@user.save!
您仍然可以事先添加:country => "US"
params[:user][:current_shipping_address][:country] = "US"
然后运行save。它真的取决于你。
答案 2 :(得分:0)
试试这种方式!
subscription = Subscription.new
address_info = params[:user].delete(:address) rescue {}
@user = User.new(params[:user].merge(:first_name => @address.first_name, :last_name => @address.last_name))
@user.subscription = subscription
@user.current_shipping_address << Address.new(address_info.merge(:country => "US"))
@user.save!
答案 3 :(得分:0)
似乎问题是地址实际上无法保存。不是因为验证而是因为'before_create'方法中的错误(是的,我知道我没有给你地址对象......我当时认为它不重要!)。
class Address < ActiveRecord::Base
# relationships
# Validators
validates_presence_of :city, :state, :country, :first_name, :last_name, :address_1
before_create :check_state
before_create :check_country
def check_state
retval = true
state.upcase!
if country == "US" and !US_STATES.map{|s| s[1]}.include?(state)
errors.add(:state, "Must be valid")
retval = false
end
retval
end
end
检查状态是否失败。但这意味着该地址通过了'有效?'电话,这似乎是所有积极的记录关心。 (这种方法确实应该是一种验证)
我已经切换到这样做了(感谢enokd的链接!):
@user = User.new(params[:user].merge(:first_name => @address.first_name, :last_name => @address.last_name))
@user.build_subscription(:subscription_plan_id => @subscription_plan.id)
@user.build_current_shipping_address(address_info.merge(:country => "US"))
我没有费心去完全调查,但是,如果地址无法保存,它将停止整个@ user.save! 就我个人而言,我认为这可能是一个小小的错误或肯定是一个意想不到的行为,但我知道什么!
答案 4 :(得分:0)
尝试:
class User < ActiveRecord::Base
# relationships
has_one :current_shipping_address, :class_name => "Address", :dependant => destroy
has_many :subscriptions, :dependant => destroy
validates :current_shipping_address, :presence => true
end