I am currently trying to use the best_in_place gem in order to do inline editing within an HTML table. I am showing a cart in cart's show view. Within the cart's show view, I have the ability to add lineItems. When an LineItem is created, a new Available record is also created with a lineItem_id and then it's shown in the cart with its lineitem. Both the Cart and LineItem tables come from an external database and because of that, I can't add columns to so that is why I can't just add an available boolean attribute to the LineItem.
**cart.rb
class Cart << AR::Base
has many LineItems
end
**line_item.rb
class LineItems <<AR::Base
belongs_to Cart
has_one :available
accepts_nested_attributes_for :available
end
**available.rb
class Available<<AR::Base
belongs_to LineItems
end
**views/cart/show.html.erb
@cart.lineitems.each do |line_items|
<td><%= line_item.price %></td>
<td><%=line_item.name %></td>
<td><%= best_in_place line_item.available.boolean, :boolean, :path => line_items_path, :type => type: :checkbox, collection: %w[No Yes] %></td>
end
I want to be able to edit the line_item.available.boolean within the html table which is on the cart show view using best_in_place but I am not having any luck.. Any help would be AMAZING! =] I know after reading around that it's not possible using nested attributes, but If I could get rid off the available model somehow and have a field in the show table that I can edit for a line_item to see whether or not the lineItem is available, that would also be great. I am open to any ideas!
Firstly, there are a few syntax issues in your code that we need to fix:
Now, the answer:
As I explain in this Github issue, you need to pass a
param
option and aurl
option (used to bepath
but that was deprecated in v3.0.0) to best_in_place.The
url
optionThe default url is the update action of the first argument to best_in_place. Since your code begins with
best_in_place line_item.available
, this would default tourl_for(line_item.available.id)
. However, you want it to PATCH the update action of the LineItemsController, i.e.url_for(line_item)
The
param
optionBy default, the param option assumes you are PATCH'ing to the AvailablesController, so here are the parameters that Rails conventions require in order to update available.boolean to the value "1":
The ID of the Available is in the URL already, so the only extra param you need to pass is the new value for
boolean
.In your case, however, you are PATCH'ing to the LineItemsController and the available model accepts nested attributes. This requires two adjustments:
The ID of the LineItem is in the URL already, but the ID of the Available is not. We have two choices here: Either put the ID of the Available into the param option, or make the ID unnecessary by passing
update_only: true
toaccepts_nested_attributes
in the model. Theupdate_only
approach may not work for you depending on your use case, but I find that it is the simplest approach the vast majority of the time and adds an extra layer of security for free.The boolean option needs to be nested properly, i.e.:
That way, when it gets to the server, the params will be:
Note that you will need to permit these attributes in the controller, i.e.:
Putting it all together, here's your best_in_place method:
However, if at all possible, use the
update_only
option.Look how much simpler it becomes now: