Javascript Rails-Ajax重画html不会';我们无法识别模型之间的关系

Javascript Rails-Ajax重画html不会';我们无法识别模型之间的关系,javascript,jquery,ruby-on-rails,ajax,Javascript,Jquery,Ruby On Rails,Ajax,因此,在通过ajax获得响应后,我用javascript重新绘制html,这很好。重画时唯一不显示的是书[i].user.full\u name 以及帮助器方法(“books[i].author”) 它说这两者都没有定义。这是否意味着如果我的模型与另一个模型有关系,我就不能重新绘制特定的html和helper方法?我怎样才能解决这个问题 因为书籍属于用户 这是我的代码: $('#priceSelect').change(function(){ $.ajax({ url: "books

因此,在通过ajax获得响应后,我用javascript重新绘制html,这很好。重画时唯一不显示的是书[i].user.full\u name
以及帮助器方法(“books[i].author”)

它说这两者都没有定义。这是否意味着如果我的模型与另一个模型有关系,我就不能重新绘制特定的html和helper方法?我怎样才能解决这个问题

因为书籍属于用户

这是我的代码:

$('#priceSelect').change(function(){
  $.ajax({
    url: "books",
    type: "GET",
    dataType: 'json',
    data: {
      sort: $('#priceSelect :selected').val(),
      title: $('.title_information').data('title'),
      university: $('.university_information').data('university')
    },
    success: function(result){
      // result gives me an array of my book objects
      var books = result;
      var length = books.length;
      var html = "";
      for (var i = 0; i < length; i++) {
        .
        .
        .
        html += "<h5 class='no-margin'>" + "<%= cutoff_text(" + books[i].author + ") %></h5>";
        html += "<h5 class='no-margin book-price-highlight'>" + books[i].price + "€</h5>";
        html += "<h5 class='no-margin'>By " + books[i].user.full_name + "</h5>";
      }
      document.getElementById("book-id").innerHTML = html
    },
  })
});
和我的index.html.erb视图

<%= content_tag :div, class: "title_information", data: {title: @title} do %>
<% end %>
<%= content_tag :div, class: "university_information", data: {university: @university} do %>
<% end %>

<select id="priceSelect">
  <option value="Best Results" selected="selected">Best Results</option>
  <option value="Price Descending">Price Descending</option>
  <option value="Price Ascending">Price Ascending</option>
</select>
.
.
.
<div class="books-info" id="book-id">
  <% @books.each do |book| %>
    <div class="col-xs-12 selectable-card">
      <%= link_to book_path(book.id) do %>
        <h4 class="index-card-title no-margin"><%= book.title %></h4>
        <h5 class="no-margin"><%= cutoff_text(book.author) %></h5>
        <h5 class="no-margin">By <%= book.user.full_name %></h5>
      <% end %>
    </div>
  <% end %>
</div>
最后是助手方法:

module BooksHelper
  def cutoff_text(string)
    string.length > 121 ? string.first(120) + "..." : string
  end
end
这是否意味着如果我的模型与另一个模型有关系,我就不能重新绘制特定的html和helper方法

不,这并不意味着。然而

前端不了解您的后端关系。这意味着您必须在json中传递所有必需的数据。因此,您需要修改
index
方法(这已经不太好了)来实现这一点

为什么?

因为全名是服务器端逻辑,您正试图调用它 从客户端javascript接收数据后,这将不起作用。 你知道我的意思吗?你能调用控制器动作吗 直接从javascript索引?不,是吗?。您必须使用ajax或html 服务器将响应数据,然后您就可以使用它了

什么是解决方案?

返回json本身的完整名称。像这样

[{full_name: "first last", id: 22, title: "Math", author: "Molissa", field: "Chemistry", price_cents: 2600, publish_year: "2007-04-28", title:"Math", user_id:15}, {…}, {…}]
怎么办?

BooksController.rb

创建index.json.jbuilder(与index.html文件位于同一文件夹中 现在)。将下面的代码粘贴到其中

创建_book.json.jbuilder(在index.html文件所在的文件夹中 请将下面的代码放入其中

并最终更改您的javascript

现在use可以像books[i]一样获取用户的全名

$('#priceSelect').change(function(){
  $.ajax({
    url: "books",
    type: "GET",
    dataType: 'json',
    data: {
      sort: $('#priceSelect :selected').val(),
      title: $('.title_information').data('title'),
      university: $('.university_information').data('university')
    },
    success: function(result){
      // result gives me an array of my book objects
      var books = result;
      var length = books.length;
      var html = "";
      for (var i = 0; i < length; i++) {
        .
        .
        .
        html += "<h5 class='no-margin'>" + "<%= cutoff_text(" + books[i].author + ") %></h5>";
        html += "<h5 class='no-margin book-price-highlight'>" + books[i].price + "€</h5>";
        html += "<h5 class='no-margin'>By " + books[i].user_fullname + "</h5>";    // check this
      }
      document.getElementById("book-id").innerHTML = html
    },
  })
});
$('#priceSelect')。更改(函数(){
$.ajax({
网址:“书籍”,
键入:“获取”,
数据类型:“json”,
数据:{
排序:$(“#价格选择:选定”).val(),
标题:$('.title_information')。数据('title'),
大学:$('大学信息')。数据('大学')
},
成功:功能(结果){
//结果为我提供了一个book对象数组
var=结果;
var length=books.length;
var html=“”;
对于(变量i=0;i
你能展示ajax响应中的内容吗???粘贴控制器和助手方法ajax响应是:[{…},{…},{…},{…}],每个{…}作为书对象-->{id:22,标题:“数学”,作者:“Molissa”,字段:“化学”,价格:2600,出版年份:“2007-04-28”,标题:“数学”,用户id:15}如果我只使用book模型中的属性重写html,效果会很好,但当我尝试在javascript中执行类似book.user的操作时,它会说这是未定义的,因为您正在从客户端javascript调用全名帮助器方法,这是行不通的。您应该在json响应中发送用户的全名,或者您应该将html页面呈现回客户端。这会给我一个500错误,说明未定义的局部变量或方法
title'for#是什么意思@标题:app/views/books/_book.json.jbuilder:2:in
_app_view_books_book_json_jbuilder__1060707560840941417_70098739575200'和此错误xhr.send((options.hasContent&&options.data)| null)@Kevin我忘了使用book对象调用属性。我更新了_book.json.jbuilder file.CheckOk,我还需要学习很多东西。我只是按照你的指示做了一些服务器端的小改动,但它工作得很好。
[{full_name: "first last", id: 22, title: "Math", author: "Molissa", field: "Chemistry", price_cents: 2600, publish_year: "2007-04-28", title:"Math", user_id:15}, {…}, {…}]
def index
  ...
  ...
  @books = @books.includes(:user)    // eager loading user. So that to reduce queries

  respond_to do |format|
    format.html
    format.json                      // dont return @books directly.will handle it in jbuilder
  end

end
json.array! @books, partial: 'books/book', as: :book
json.id book.id
json.title book.title
json.author book.author 
json.field book.field
json.price_cents book.price_cents
json.publish_year book.publish_year

json.user_id book.user_id
json.user_fullname  book.user.full_name            // here we are sending user's fullname.
$('#priceSelect').change(function(){
  $.ajax({
    url: "books",
    type: "GET",
    dataType: 'json',
    data: {
      sort: $('#priceSelect :selected').val(),
      title: $('.title_information').data('title'),
      university: $('.university_information').data('university')
    },
    success: function(result){
      // result gives me an array of my book objects
      var books = result;
      var length = books.length;
      var html = "";
      for (var i = 0; i < length; i++) {
        .
        .
        .
        html += "<h5 class='no-margin'>" + "<%= cutoff_text(" + books[i].author + ") %></h5>";
        html += "<h5 class='no-margin book-price-highlight'>" + books[i].price + "€</h5>";
        html += "<h5 class='no-margin'>By " + books[i].user_fullname + "</h5>";    // check this
      }
      document.getElementById("book-id").innerHTML = html
    },
  })
});