ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-darwin14]
Rails 4.2.5.2
So I've been struggling with this for a couple of days and not sure where to focus. My scenario: My user clicks a button on a source request view at REQUEST/index that creates a new row in my PERFORMANCE destination table and assigns attributes from the source. At the same time I need to flip a boolean attribute in the source table (REQUEST).
My code is below:
REQUEST VIEW
<%= new_performance_path( :attribute_id1 => (source.attribute_id1), :attribute_id2 => (source.attribute_id2), :attribute_id3 => (source.attribute_id3)), class: "btn btn-success" %>
PERFORMANCE 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
While the code creates the new row in my PERFORMANCE table I can't figure out the method syntax to effectively flip the REQUEST table attribute to "false". This code with the if statement processes without throwing an erorr. I've originally tried this in the PERFORMANCE CONTROLLER/NEW, without the if statement, which results in an internal server error:
def new
...
@request.available = false
@request.save
...
end
RAILS CONSOLE
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'
So I think this means I can't call available on request in my performances model. Based on that I tried to add a method to my PERFORMANCE model...
PERFORMANCE.RB
def available
Request.where( :available == true )
end
...but the error persists. My thinking is that I need to grab all rows in the REQUEST table where the boolean value 'available' is equal to true.
Note that these two tables are not directly related to each other. REQUESTS is a join table in my domain model. The app is a music request app, so a USER has_many :REQUESTS, and :PERFORMANCES and I'm using existing rows in the REQUEST table to build new rows in the PERFORMANCE table, but need to edit the row in the request table when a new row is created in performance.
Thanks guys. Still learning being new to Rails and I struggle with referential relationships especially. Thanks for taking a look and helping me out.
@Shishir - After more research on Stack I ended up making my model fatter with a new method & thinning out the controller. This appears to have worked.
PERFORMANCE 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
This effectively sets the request to 'false' which displays as expected in my request view. Thanks for your help buddy and forcing me to think about this differently. Cheers, my friend.