如何编写一个 Ruby 方法,允许我在目标 table 中创建新行,同时在源 table 中编辑属性?

How can I write a Ruby method that allows me create a new row in a destination table while editing an attribute in the source table?

ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin14]
Rails 4.2.5.2

所以我已经为此苦苦挣扎了几天,但不确定应该关注哪里。我的场景:我的用户在 REQUEST/index 处的源请求视图上单击一个按钮,在我的 PERFORMANCE 目标 table 中创建一个新行并从源分配属性。同时我需要翻转源中的布尔属性 table (REQUEST)。

我的代码如下:

请求查看

<%= new_performance_path( :attribute_id1 => (source.attribute_id1), :attribute_id2 => (source.attribute_id2), :attribute_id3 => (source.attribute_id3)), class: "btn btn-success" %>

表现CONTROLLER/NEW

def new
    @performance = Performance.new(:attribute_id1 => params[:attribute_id1], :attribute_id2 => params[:attribute_id2], :attribute_id3 => params[:attribute_id3] )
    @performance.completed = false
    @performance.save
    if @request.present?
      @request.available = false  #  Need to assign 'false' to this boolean attribute
      @request.save  #  Then save it.
    end
    redirect_to :performances
end

虽然代码在我的 PERFORMANCE table 中创建了新行,但我无法找出有效地将 REQUEST table 属性翻转为 "false" 的方法语法。这段带有 if 语句的代码处理时不会抛出错误。我最初在 PERFORMANCE CONTROLLER/NEW 中尝试过这个,没有 if 语句,这会导致内部服务器错误:

  def new
    ...
    @request.available = false
    @request.save
    ...
  end

RAILS 控制台

Completed 500 Internal Server Error in 29ms (ActiveRecord: 10.1ms)

NoMethodError (undefined method `available=' for nil:NilClass):
  app/controllers/performances_controller.rb:26:in `new'

所以我认为这意味着我无法在我的表演模型中调用 available on request。基于此,我尝试向我的 PERFORMANCE 模型添加一种方法...

PERFORMANCE.RB

  def available
    Request.where( :available == true )
  end

...但错误仍然存​​在。我的想法是,我需要获取 REQUEST table 中布尔值 'available' 等于 true 的所有行。

请注意,这两个 table 彼此没有直接关系。 REQUESTS 是我域模型中的一个连接 table。该应用程序是一个音乐请求应用程序,因此用户 has_many :REQUESTS 和 :PERFORMANCES 并且我正在使用 REQUEST table 中的现有行在 PERFORMANCE table 中构建新行,但需要在性能中创建新行时编辑请求 table 中的行。

谢谢大家。仍然是 Rails 的新手,尤其是在参考关系方面我很挣扎。感谢您查看并帮助我。

@request 对象在您的控制器操作新中为 nil。因此错误

undefined method `available=' for nil:NilClass

初始化@request 应该可以修复上述错误。

编辑 1: ** 写了伪代码,请看评论有解释。

def new
  # Load the user objects
  @user = User.find(params[:user_id])

  # User has many performances, use build method to associated 
  # user and newly build performance.
  @user.performance.build({
    :attribute_id1 => params[:attribute_id1], 
    :attribute_id2 => params[:attribute_id2], 
    :attribute_id3 => params[:attribute_id3],
    :completed     => false;
  })

  # User has one request (This is an assumption). 
  # if its is  has many you can use the above mentioned method to 
  # create new request method same as performance.
  if @performance.save
      @user.request.available = false  #  Need to assign 'false' to this boolean attribute
      @user.request.save  #  Then save it.
    end
  end
  redirect_to :performances
end

@Shishir - 在对 Stack 进行更多研究后,我最终使用一种新方法使我的模型变得更胖,并精简了控制器。这似乎奏效了。

表现CONTROLLER/NEW

 def new
    ...
    @performance.save
    # After @performance is saved we point to new method in performance.rb
    @performance.remove_request
    # it then comes back for the redirect
    redirect_to :performances, notice: "..."
  end

performance.rb

  def remove_request
    @request = Request.find_by(:available => true)
    if @request.available == true
      @request.available = false
    end
    @request.save
  end

这有效地将请求设置为 'false',它在我的请求视图中按预期显示。感谢您的帮助伙伴,并迫使我以不同的方式思考这个问题。干杯,我的朋友。