我有一个模型,一本书,有一个 has_many 关联,拥有。我已将其设置为用户可以单击按钮将书籍添加到他们的收藏中。 Controller 看起来像这样:
def create
@book.owns.where(user_id: current_user.id).first_or_create
@own = Own.where(user_id: current_user.id, book_id: @book.id)
Own.update(@own, :quantity => "1")
respond_to do |format|
format.html { redirect_to @book}
format.js
end
end
View 如下所示:
<% if user_signed_in? && current_user.owns?(@book) %>
<%= link_to book_own_path(@book), method: :delete, remote: true, class: "btn btn-danger btn-circle", title: "Remove from collection", data: { toggle: "tooltip", disable_with: "<span class='fa fa-minus'></span>"} do %><span class="fa fa-heart-o"></span><% end %>
<% else %>
<%= link_to book_own_path(@book), method: :post, remote: true, class: "btn btn-success btn-circle", title: "Add to collection", data: { toggle: "tooltip", disable_with: "<span class='fa fa-plus'></span>"} do %><span class="fa fa-heart"></span><% end %>
<% end %>
这样,当单击该按钮时,它会自动将数量 1 添加到其库存中。我想要做的是让用户能够从图书展示 View 中更新他们拥有的数量,所以我添加了以下内容:
<% if user_signed_in? && current_user.owns?(@book) %>
<span id="<%= @book.id %>_quantity">
<% Own.where(:user_id => current_user.id, :book_id => @book.id).each do |z| %>
<% if z.quantity == 1 %>
<form>
You own <input type="text" placeholder="<%= z.quantity %>" id="quantity" name="quantity" size="1" class="text-center" /> copies of this book
<input type="submit" onclick="<% Own.update(@own, :quantity => params[:quantity]) %>.submit();" hidden />
<form>
<% else %>
<form>
You own <input type="text" placeholder="<%= z.quantity %>" id="quantity" name="quantity" size="1" class="text-center" /> copies of this book
<input type="submit" onclick="<% Own.update(@own, :quantity => params[:quantity]) %>.submit();" hidden />
<form>
<% end %>
<% end %>
<br />
</span>
<% end %>
当我单击 Enter 时,上面的内容会更新自己的数量,但它会将我重定向到相同的网址,并在末尾添加 ?quantity=1 (或任何数量值)。除非刷新页面,否则它也不会在输入占位符中显示数量。
我的问题是,有没有更好的方法来解决这个问题,或者有没有办法实际显示占位符值。另外,如何在后台提交表单而不是刷新页面的情况下设置此设置?
最佳答案
要在 Rails 中构建表单,您应该使用 Rails 提供的内容: Rails doc for Form helpers
或者像 SimpleForm 这样的 gem
此示例假设您使用的是 Rails 4+。
首先,您想要显示您的书籍页面,因此加载您的书籍并加载您自己的书籍(当您操作模型时最好在 Controller 中执行此操作):
# Books Controller
def show
@book = Book.find(params[:id])
@owns = current_user.owns.where(book: @book)
end
你的观点现在可能是这样的:
# Book show
<% @owns.each do |own| %>
<div> You own <span class="<%= own.id %>_quantity"><%= own.quantity %></span> of this book </div>
<%= form_for own, remote: true, method: :put do |f| %>
<%= f.hidden_field :quantity, value: own.quantity + 1 %>
<%= f.submit "Add One" %>
<% end %>
<hr>
<% end %>
我们迭代我们自己的表单并创建一个将数量加 1 的表单。由于表单上的 PUT 方法,该请求将转到 Own#update。由于属性“remote: true”,表单将通过 AJAX 发送(这是在表单中使用 AJAX 的 Rails 方法之一:Rails doc for AJAX)。
# Own Controller
def update
@own = Own.find(params[:id])
respond_to do |format|
if @own.update(own_params)
format.html do
redirect_to book_path(@own.book), notice: 'success'
end
format.js
else
format.html do
redirect_to book_path(@own.book), alert: 'fail'
end
end
end
end
def own_params
params.require(:own).permit(:quantity)
end
在这里,我们将加载我们自己的并尝试更新它。如果禁用 JS,请求将采用 HTML 部分并重定向到您想要的位置。如果启用了 JS,那么您可以创建一个“JS View ”,其呈现方式与 html View 完全相同(您必须以操作名称来命名它们)。所以,它可能是这样的:
# views/owns/update.js.erb
$(".<%= @own.id %>_quantity").html("<%= @own.quantity %>");
它将用新数量替换范围的内容。
我还没有测试过,但最后,你的代码可能是这样的
关于javascript - Rails 关联表单与 Ajax 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33466773/