【问题标题】:callback messing with form submit回调弄乱了表单提交
【发布时间】:2013-06-05 01:26:25
【问题描述】:

好的,这就是发生的事情..

用户模型有一些方法,它们的功能取决于是否存在其他称为 status_updates 的对象,这些对象以 has_many belongs_to 关系与之关联。

所以现在我意识到 status_updates 新页面上有一个表单,并且控制器提供了一个已初始化但未为该表单保存的 status_update.build 对象。虽然,当从视图中调用用户方法时,它会返回未保存的初始化值,而不是访问数据库以返回 NilClass。

我通过在需要它的用户方法上设置以下条件来修复该错误。

if self.status_updates.count == 0
  temp_status_update
else
  self.status_updates.last
end 

如果用户对象没有任何 status_updates,则返回一个已初始化的 status_update,其中包含默认值 - 此 status_update 不会被保存。在实际创建和保存 status_update 之前,它只是一个占位符。

这就是奇怪的地方......

现在,当我尝试实际保存 status_update 时,无论我通过表单提交什么,它都只会保存初始化的默认值。

我知道这些值正在被提交,但这些值似乎并没有提交给控制器。

这是我的 status_updates 控制器中的操作。

   def create
      @status_update = current_user.status_updates.build(params[:status_update])
      if @status_update.save
        flash[:success] = "Status Update Saved! #{params[:status_update]}"
      # redirect_to status_update_path(current_user.id)
        redirect_to new_status_update_path
      else
        flash[:error] = "Input Error - Couldn't Save Status Update"
        redirect_to new_status_update_path
      end 
    end  



   def new
     @status_update = current_user.status_updates.build if user_signed_in?
   end 

参数不应该有提交的值而不是默认的初始化值吗?

我在成功闪存中返回参数,这会将正确的值返回给视图。

这里是 status_update 模型:

    class StatusUpdate < ActiveRecord::Base
      belongs_to :user

      after_initialize :default_values 
      before_create :sanitize 

      #removed stuff from here for brevity

      def default_values
        if self.created_at == nil
          self.current_bf_pct        = 0
          self.current_weight        = 0
          self.current_lbm           = 0    
          self.current_fat_weight    = 0
          self.change_in_weight      = 0 
          self.change_in_bf_pct      = 0
          self.change_in_lbm         = 0
          self.change_in_fat_weight  = 0
          self.total_weight_change   = 0
          self.total_bf_pct_change   = 0
          self.total_lbm_change      = 0
          self.total_fat_change      = 0 
        end
      end

      #removed rest of model from here for brevity

这是用户模型

    class User < ActiveRecord::Base


      before_create :sanitize

      has_many :status_updates, dependent: :destroy

     #removed stuff from here for brevity

    def sanitize
      #inputs
      self.activity_factor       = 1.3
      self.deficit_amnt          = 1
      self.target_bf_pct         = 10 
      self.fat_factor            = 0.45
      self.protein_factor        = 1
    end

    #Removed functions for brevity


      def temp_status_update
        self.status_updates.build
      end
    end

我用来提交 status_update 的表单

        <%= form_for(@status_update) do |f| %>

          <%= f.label :current_weight %>
          <%= f.text_field :current_weight %>

          <%= f.label :current_bf_pct %>
          <%= f.text_field :current_bf_pct %>

          <%= f.submit "Update", class:"btn btn-large btn-primary" %> 
        <% end %>

这是从新的 status_update 视图对用户模型的方法调用

        <tr>
          <td> <%= current_user.current_bf_pct %> % </td>
          <td> <%= current_user.target_bf_pct  %> % </td>
        </tr> 

不过,提交给 create 操作的 status_update 构建仍存储在 @status_update 变量中。

因此,为什么还要考虑 OTHER status_update 构建?它没有被插入到传递给创建操作的变量中。

【问题讨论】:

  • 我的问题是否得到充分解释、太长或难以理解?大声笑我如何确保其他人愿意回答我的问题?我尽量说清楚。

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


【解决方案1】:

当你想在任何操作之后设置属性时,你应该像这样设置它们并调用该方法 after_create、after_update 等...

模型回调适用于数据库中填充的所有数据。

before_create :sanitize    

def sanitize
self.users.build(user_id, User.current.id, activity_factor:1.3,
  deficit_amnt: 1
  target_bf_pct: 10 
  fat_factor: 0.45
  protein_factor: 1)
end

对您想要更新或设置值的任何模型执行相同操作...它只会从控制器调用该方法并从模型中检查它们以使其正常工作。

【讨论】:

    【解决方案2】:

    切勿使用默认模型值来创建临时对象。

    与其避开数据库,不如在模型中添加一个名为“temporary”的属性,并在创建临时对象时将其设置为“true”。然后使用 find_by_temporary 找到它并根据需要进行销毁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 2014-02-05
      • 2018-11-17
      • 2015-04-12
      • 1970-01-01
      • 2020-01-16
      相关资源
      最近更新 更多