我有一个拥有has_many协会的模型,书籍。我已经设置了用户可以单击按钮将书籍添加到其集合的位置。控制器看起来像这样:
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
视图如下:
<% 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添加到其库存中。我想要做的是让用户能够从书籍展示视图更新他们拥有的数量,所以我添加了这个:
<% 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 %>
当我点击进入时,上面的DOES会更新自己的数量,但是它会将我重定向到相同的网址,其中数量= 1(或数量值不等)添加到结尾。除非刷新页面,否则它也不会在输入占位符中显示数量。
我的问题是,有没有更好的方法来解决这个问题,或者有没有办法真正显示占位符值。另外,如何在后台提交表单而不是刷新页面?
答案 0 :(得分:1)
要在Rails中构建表单,您应该使用Rails为您提供的内容: Rails doc for Form helpers
或宝石喜欢SimpleForm
此示例假设您使用的是Rails 4 +。
首先,您要显示您的图书页面,因此请加载您的图书并加载您自己的图书(当您在控制器中操作模型总是更好的时候):
# 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。表单将通过AJAX发送,因为属性“remote:true”(这是在表单中使用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视图”,其呈现方式与html类似(您必须在操作名称后面命名)。所以,它可能是这样的:
# views/owns/update.js.erb
$(".<%= @own.id %>_quantity").html("<%= @own.quantity %>");
它将用新数量替换范围的内容。
我还没有测试过,但最后,你的代码可能是这样的