Ruby on Rails使用动态内容和局部视图呈现表格

3
我曾经多次使用这个网站找答案,但很遗憾,我现在被卡住了,需要一些帮助。在我正在工作的主要内容页面中,我使用CSS和div ids来创建表格时遇到了问题。

总览

该表格由2行6列组成,然后分为12个盒子,每个盒子大小为200px X 200px。现在,每个盒子的内容都包含一个新项(@books),该项是从单独的控制器(使用内置的生成脚手架命令)生成的。我还使用分页来限制页面上的项目数量(12个),因此旧项目会消失。

问题

我能够通过在我的控制器和视图上使用以下代码来填充每个12个盒子的内容:

控制器

def content
@books= Book.paginate(:page => params[:page], :per_page => 12)
respond_to do |format|
  format.html # content.html.erb
end

查看 {content.html.erb}

<% @books.each do |book| %>
  <div id="column1">
      <tr>
        <td><%= book.name %></td>
        <td><%= book.title %></td>
        <td><%= book.content %></td>
        <td><%= link_to 'Show', book %></td>
     </tr>
  </div>
    <% end %>
<br />
<div id="paginate">
    <%= will_paginate(@books, 
) %)
</div>
</div>

生成视图时发生的情况是,所有内容正常渲染,但我的所有书籍都使用相同的“列1”。
     <div id="column1">
      <tr>
        <td>Title</td>
        <td>Name</td>
        <td>Content</td>

        <td><a href="/books/4d376fc63060da4abc000002">Show</a></td>
     </tr>
  </div>
  <div id="column1">
      <tr>
        <td>Title </td>
        <td>Name</td>
        <td>Content</td>

        <td><a href="/books/4d3c96383060da31c9000001">Show</a></td>
     </tr>
  </div>

我希望每本书都有自己的列{2, 3,4,...12},这样我就可以使用jquery单独定位每本书。另一个问题是,我想在
标签中使用render partial来处理所有内容,但是当我使用render partial时,它会将所有项目放在1列 {relisting of Book.all}中,所以它只重复了所有包含的信息。我感觉应该使用另一种方法或编辑当前方法来完成这个过程,但我不确定要去哪里编辑。谢谢!
greenz
更新
嗨Mike,我真的很感激你尝试向新手解释发生了什么。基本上,我回到了第一步,并将每个代码片段应用到看看在哪里出现问题。你正在非常棒地解释问题,但当渲染代码时,我无法理解发生了什么,因为渲染和布局的ruby文档非常基础,没有任何示例可以让我看到div_for标记如何影响渲染过程(我是一个视觉化的人)。我想向您展示新代码,但评论不允许我这样做,所以我打开了一个答案 :(
第一个编辑是删除

标记。
<% @books.each do |book| %> 

替换为

<table> 
   render @books
</table>

现在我的代码看起来像这样 {content.html.erb}。
<div id="maincontent">

    <table>
    render @books
    </table>
    <div id ="column1">
        <tr>
            <td><%= book.name %></td>
            <td><%= book.title %></td>
            <td><%= book.content %></td>
            <td><%= link_to 'Show', book %></td>
        </tr>

    </div>  
    <% end %>
    <br />

    <div id="paginate">

    <%= will_paginate(@books, 
    ) %>
    </div>
</div>

当我应用这个代码时,渲染视图时出现了意外的结束错误,并指向我的代码的最后一行。(当在结尾添加结束标签时,它只会抛出另一个错误) 所以我将渲染页面从_bookcontent.html.erb更改为_book.erb,并像所示在column1 div之间插入了partial。

    <div id ="column1">

        <%= render :partial => "book" %>

    </div>  

<% end %>

我现在明白这个标签的作用了,它告诉我的局部代码,在渲染每本书时从数据库中获取最新的书籍ID。因此,现在渲染@books语句正在为我插入的每个渲染页面跟踪书籍ID。(我可能会有所误解,但这就是我理解的方式)。现在进入臭名昭著的_book.erb,这个页面正在渲染我的代码。

<% div_for(book) do %>
<tr>
    <td><%= book.name %></td>
    <td><%= book.title %></td>
    <td><%= book.content %></td>
    <td><%= link_to 'Show', book %></td>
</tr>
<% end %>

根据我的阅读,<% div_for(book) do %> 是在每本书周围包装一个独特的div id,例如:

 <div id="book_123"> Book.name / Book.Title </div>

这个 div 现在包含在我之前的 column1 div ID 中,它拥有我列/盒子的所有样式。由于 div_for 标签上缺乏信息,我仍然遇到代码中的错误和意外结束。(尝试使用 ruby -w 调试 _book.erb 不起作用,所以我不知道如何使用结束标记)。这些是我正在尝试纠正的要点,以保持清醒。

  1. 我应该从我的内容页面中删除 <div id="column1"> 并在我的内容页面的其他位置应用新的 div id / class 吗?

  2. 我应该在部分页面和我的 content.html.erb 中的分页之前插入 <% end %> 标签吗?当我同时拥有两个标签时,似乎渲染器会抱怨每个页面末尾的意外结束。

  3. 当用你的代码替换我的代码时,我收到了上述意外结束,但这并不是因为你的问题,我肯定是在我的代码中缺少了某个组件。

  4. 我可能从布局角度错误地处理了这个问题,但我的主要目标是有 2 行 6 个盒子/列,每个盒子都包含不同的书。然后使用分页向后滚动到早期的书,并应用相同的布局,现在它做得很好,但我为每本书使用了相同的列 id,需要单独定位所有盒子。

3个回答

3
如果我理解正确,这只是它按照你说的去做,而不是你想要的结果。无论哪个控制器有content方法,都应该像这样:
```php // 代码示例 ```
def content
  @books = Book.paginate :page => params[:page], :per_page => 50
end

你的视图应该像这样(虽然是旧语法,但仍然应该正常工作)。
content.html.erb:
<div id="maincontent">
  <table>
    <%= render :partial => 'book', :collection => @books %>
  </table>
  <br />
  <%= will_paginate @books %>
</div>

或者尝试新的语法。新的语法很奇怪,我个人还没有尝试过,但我认为这应该可以工作。因此,这是替代方案,更适用于Rails 3版本的content.html.erb:

<div id="maincontent">
  <table>
    <%= render @books %>
  </table>
  <br />
  <%= will_paginate @books %>
</div>

我认为它是根据类名和是否可枚举来选择部分内容。

_book.html.erb 部分内容:

<%= div_for(book) do %>
<tr>
    <td><%= book.name %></td>
    <td><%= book.title %></td>
    <td><%= book.content %></td>
    <td><%= link_to 'Show', video %></td>
 </tr>
<% end %>
Div_for 是秘密酱。
唯一必需的结尾是在局部视图中关闭块的那个。

我修复了代码。我忘记在div_for语句的末尾加上“do”。请注意,我在视图中有表格标签,而div和tr标签将在局部视图中创建。 - mikewilliamson

0
Now i am getting unexpected end errors when i render the page here is my view

view = content.html.erb

    <div id="maincontent">

    render @books
      <div id="column1">
        <tr>
            <%= render :partial => "bookcontent" %>
        </tr>
      </div>
        <% end %>
    <br />
      <div id="paginate">
        <%= will_paginate(@books, 
        ) %>
      </div>
    </div>

Here is my render partial = _bookcontent.html.erb
   <% div_for(book) %>
<tr>
    <h3><%= book.name %></h3>
    <h3><%= book.title %></h3>
    <h3><%= book.content %></h3>
    <h3><%= link_to 'Show', book %></h3>
</tr>
<% end %>

我也不知道是该使用div的id还是class。默认情况下,我总是只使用一个id。


Rails著名的“约定优于配置”之一是名称非常重要。部分的名称将用作内部变量的名称。_book表示局部变量“book”将在部分内创建。您将部分命名为_bookcontent,但正在使用未创建的变量“book”。同时,Rails已基于您使用的名称创建了一个var _bookcontent。请记住,您正在传递书籍(模型)的集合,并且每本书都将呈现一次部分。 - mikewilliamson
顺便说一句,通常情况下,你应该编辑原始问题并添加更多细节,或者在评论中进行一些来回交流,而不是在自己的问题中添加另一个答案。不过,他们真的应该允许你在评论中放置代码。 - mikewilliamson
看起来在第一列div关闭后可能有一个孤立的“end”。 - Josh Kovach
感谢Mike和Josh的评论,我已经更新了我的问题以反映这些更改。 - greenz
已更新。请尝试并告诉我发生了什么。显然,我使用HAML已经足够长时间,以至于我忘记了ERB的工作方式。 :( - mikewilliamson
Div_for是Mike的秘密武器!感谢你向我展示如何正确使用它。我从未想过会这么说,但那个命令是一段性感的代码。嘿,你有关于如何使用HAML的好教程吗? - greenz

-1

如果我理解正确,您的代码运行正常,但您想要:

column1
column2
column3
...

对于每一本书,如果是这种情况,为什么不直接替换:

 <div id="column1">

使用

 <div id="column#{@book.id}">

或使用计数器

<%
 book_counter=0
 @books.each do |book| 
 book_counter = book_counter+1
%>
  <div id="column#{book_counter.to_s}">

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接