【问题标题】:New acts like create创建等新行为
【发布时间】:2012-05-07 11:55:12
【问题描述】:

在我的创建操作中,方法 new 的行为类似于创建。

def create
  @page = Page.new(params[:page].merge(:user_id => current_user.id ))
  if @page.save
    flash[:notice] = t("success")
    redirect_to pages_path
  else
    render :new
  end
end

当我使用带有参数的新对象时,ActiveRecord 在数据库中创建新对象。 Page.new 在我的控制器中的新操作中运行良好。可能是什么原因?我的模型中没有重写方法 new 和回调(before_save、before_create 等)。任何帮助将不胜感激。

更新 - 来自调试器的代码

.../app/controllers/pages_controller.rb:48
@page = Page.new(params[:page].merge(:user_id => current_user.id ))
(rdb:25) @page
nil
(rdb:25) n
.../app/controllers/pages_controller.rb:49
if @page.save
(rdb:25) @page
#<Page id: 80 ... >
(rdb:25) Page.last
#<Page id: 80 ... >
(rdb:25) @page.save
false

【问题讨论】:

  • dude page.save 触发了那个东西:P
  • 你怎么知道它在调用Page.new..时会在数据库中创建新记录,然后将其保存到数据库@page.save@page.save 将在数据库中创建新记录。这是正在发生的事情吗?你想让这段代码做什么?
  • 我的模型中有验证,所以如果它们失败,@page.save 将返回 false 并且应用程序将呈现操作“新”。我确定,那 Page.new(params[:page].merge(:user_id => current_user.id )) 正在数据库中保存记录 - 用调试器找到它
  • @zachar 那不可能,伙计。新的不能“保存”对象。
  • 'new' 理论上可以保存模型,如果有某种回调来保存对象。模型中有回调吗?

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


【解决方案1】:

检查我的内联 cmets..

 def create
  @page = Page.new(params[:page].merge(:user_id => current_user.id )) # you trigger new thats fine..
  if @page.save # Notice here.. This line is triggering query on database.
    flash[:notice] = t("success")
    redirect_to pages_path
  else
    render :new
  end
end

【讨论】:

  • 如果验证失败,@page.save 将返回 false,因此对象不会保存在数据库中。如果对象有效,则代码有效。我想这不是我的问题的正确解决方案。
【解决方案2】:

原因(模型中可以改变工作流状态的方法):

def status=(state_name)
  states = [self.current_state.to_sym]
  possible_states.each {|t| states<< t[1]}
  unless state_name.blank?
    if states.include? state_name
    process_event! state_name
    end
  end
end

丑陋的修复

def create
  @page = Page.new
  if @page.update_attributes(params[:page].merge(:user_id => current_user.id )) && @page.save
    flash[:notice] = t("success")
    redirect_to pages_path
  else
    render :new
  end
end

错误非常愚蠢,我并不为自己的解决方案感到自豪。无论如何,谢谢你的帮助:)

【讨论】:

    【解决方案3】:

    【讨论】:

    • 那将是@page.create,在控制器中没有“创建”方法。这个答案似乎不正确。
    • 嗯? OP 谈论的是 AR 模型方法,而不是控制器方法。
    • 哦 - 我现在明白你的意思了。我以为您是在暗示 OP 应该使用@page.create。我误会了。
    【解决方案4】:

    您的控制器代码是正确的。这就是“创建”控制器方法的工作方式。问题不存在。

    您确定要创建两个模型吗?

    您使用属性调用的.new 方法会在内存中创建一个未保存的活动记录对象。 .save 方法保存它。最后(假设数据有效)你应该在内存中有一个对象。

    如果你创建了两个对象,那就有问题了。如果你只有一个,那么它应该是。

    您是否有通过此控制器方法创建的第二个对象?

    流程应该是:

    # when GET /student/new is called, this returns an empty object to display in the form
    # for the user to see.
    def new
      @page = Page.new
    end
    
    # When POST /page is called, the form params are passed in here.
    def create
      # First, generate a new page object with the params passed in.
      @page = Page.new(params[:page].merge(:user_id => current_user.id ))
      # Now try save the object to persist it in the database.
      if @page.save
        flash[:notice] = t("success")
        redirect_to pages_path
      else
        render :new
      end
    end
    

    【讨论】:

    • 如果 new 确实在创建一个对象, save 不能创建另一个,它只会更新它。 @page 将始终指向同一个对象。
    • @Beerlington 我明白了。我理解 OP 说他正在保存 2 个对象——一个在 new 上,一个在 save 上。可能我理解错了。
    • @Beerlington 如果您阅读了我的回答,它是 100% 正确的。我不确定为什么投反对票——你能详细说明一下吗?
    • 只有在对象无效时才会出现错误 - 应用程序重定向到表单时出现验证错误,但对象已存储在数据库中
    • 尝试将.save 替换为.save! - 这应该会为您提供有关记录存在验证错误的原因的更多信息。代码看起来不错。我认为问题出在其他地方。
    猜你喜欢
    • 2014-04-28
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 2015-07-30
    • 2018-09-08
    • 2020-09-08
    相关资源
    最近更新 更多