如何为真实模型属性定义虚拟属性然后保存?

时间:2011-10-17 09:00:05

标签: ruby-on-rails ruby ruby-on-rails-3

在我的应用程序中,我尝试在我的User模型中创建一个date_select的虚拟属性,该属性将自己与我的UserPrice模型的date_select相关联。原因是,我试图只有一个用户必须选择的日期下拉列表。我计划通过使User虚拟date_select将我的所有UserPrice date_selects更新到该特定日期来实现此目的。

我的UserPrice模型包含:purchase_date属性:

create_table :user_prices do |t|
      t.decimal :price
      t.date :purchase_date

我有一个嵌套的表单,可以通过查看我的UserPrice控制器来显示,该控制器也在create更新表单上生成的所有UserPrices:

UserPrices Controller

  def add_store_prices
     @a_new_user = User.new
     5.times do
        @a_new_user.user_prices.build
     end
  end

  def create
    respond_to do |format|
      if current_user.update_attributes(params[:user])
        redirect_to :back
      else
        redirect_to :back
      end
    end
  end

然后我尝试在User模型中定义如何更新:purchase_dates的属性,并使f.date_select字段起作用:

class User < ActiveRecord::Base
attr_accessible :user_prices_attributes, :all_dates
has_many :user_prices
attr_writer :all_dates

def all_dates
# @all_dates  = UserPrice :purchase_date field?
    #Needs to update the :purchase_date of the UserPrices
end

我不确定从哪里开始。 如何定义虚拟属性:all_dates并让它更新以创建我的表单上生成的所有UserPrice:purchase_date属性?

最终结果应如下所示:

<%= form_for(@a_new_user, :url => {:controller => :user_prices, :action => :create}) do |f| %>
 <%= f.error_messages %>
  <%= f.date_select :all_dates  %>
    <%= f.fields_for :user_prices do |pf| %>
      <%= pf.text_field :product_name %>
      <%= pf.text_field :store %>
      <%= pf.text_field :price %>
    <% end %>
 <%= f.submit %>
<% end %>

谢谢,真的需要一些帮助。

修改

这是我用以下控制器代码得到的错误:

attr_accessor :all_dates
  after_save    :save_all_dates_to_user_prices

  protected

  def save_all_dates_to_user_prices 
    if !self.all_dates.nil?       
      self.user_prices.update_all :purchase_date => self.all_dates
    end
  end


ActiveRecord::MultiparameterAssignmentErrors in UserPricesController#create

1 error(s) on assignment of multiparameter attributes

app/controllers/user_prices_controller.rb:30:in `block in create'
app/controllers/user_prices_controller.rb:29:in `create'

"utf8"=>"✓",
 "authenticity_token"=>"fmB0kymP2vetFDoI/BB6RkyMEgsnhvf04cJ5Vu1GEaI=",
 "user"=>{"all_dates(2i)"=>"10",
 "all_dates(3i)"=>"17",
 "all_dates(1i)"=>"2011",
 "user_prices_attributes"=>{"0"=>{"product_name"=>"Cherries",
 "store"=>"4255 Alafaya Trail,
 Oviedo,
 FL 32765,
 USA",
 "price"=>"2.99"},
 "1"=>{"product_name"=>"",
 "store"=>"",
 "price"=>"5.99"},
 "2"=>{"product_name"=>"",
 "store"=>"",
 "price"=>""},
 "3"=>{"product_name"=>"",
 "store"=>"",
 "price"=>""},
 "4"=>{"product_name"=>"",
 "store"=>"",
 "price"=>""}}},
 "commit"=>"Done"}

1 个答案:

答案 0 :(得分:2)

就用户模型而言,你非常接近:

class User < ActiveRecord::Base

  # See: http://gabeodess.heroku.com/posts/14
  composed_of :all_dates, :class_name => "DateTime",
    :mapping => %w(Time to_s),
    :constructor => Proc.new { |item| item },
    :converter => Proc.new { |item| item }

  after_save    :save_all_dates_to_user_prices

  protected

  def save_all_dates_to_user_prices 
    if !self.all_dates.nil?       
      self.user_prices.update_all :purchase_date => self.all_dates
    end
  end

end

我会告诉你最好的方法来决定all_dates何时获得保存。在我给出的示例中,all_dates用于在保存用户后(在更新或创建期间)更新用户的价格,并且仅在all_dates不为零时(例如,每当输入在表格上提供)。

我假设您已将用户模型设置为accepts_nested_attributes_for :user_prices。我不太明白为什么要在UserPrices的create方法中更新当前用户,但我没有看到代码本身有任何问题。