对Ruby on Rails中的嵌套感到沮丧

时间:2012-10-05 22:26:44

标签: ruby-on-rails-3 foreign-keys has-many-through belongs-to nested

这是我在这里发表的第一篇文章,老实说,我不会提出很多问题,但是在Ruby on Rails中嵌套很长一段时间以来,一直困扰着我。

我有一个class Thought(成员的个人帖子),分页为@share_items。我提供了一个类似按钮,允许会员喜欢其他会员的帖子(如Facebook)。 “赞”按钮具有class Opinion

到目前为止我的代码:

Class Member
has_many :thoughts, dependent: :destroy
has_many :opinions, foreign_key: "fan_id", dependent: :destroy
has_many :fans, through: :opinions

Class Thought
belongs_to :member

has_many :opinions, foreign_key: "like_id", dependent: :destroy
has_many :likes, through: :opinions

validates :member_id, presence: true

Class Opinion
attr_accessible :like_id

belongs_to :fan, class_name: "Member"
belongs_to :like, class_name: "Thought"

validates :fan_id, presence: true
validates :like_id, presence: true

Member Model
def share
Thought.from_members_authenticated(self)
end

MemberPages Controller
def homepage
@share_items = registered_member.share.paginate(page: params[:page])
end

部分_share.html.erb

<% if @share_items.any? %>
<ol class="member_shares">
<%= render 'shared/share_item', collection: @share_items %>
</ol>
<%= will_paginate @share_items %>
<% end %>

其中呈现部分_share_item.html.erb

<li id="<%= share_item.id %>">
content...
<%= render 'thoughts/like_form' %>
...content
</li>

在我尝试在分页thoughts/like_form@share_items)内呈现表单class Thought之前,一切顺利。它有奇怪和无法解释的结果(对我来说)。以下是表单中的代码。

Member Model

def liked?(random_thought)
opinions.find_by_like_id(random_thought.id)
end

def like!(random_thought)
opinions.create!(like_id: random_thought.id)
end

def unlike!(random_thought)
opinions.find_by_like_id(random_thought.id).destroy
end

OpinionsController

respond_to :html, :js

def create
@thought = Thought.find(params[:opinion][:like_id])
registered_member.like!(@thought)
respond_with @thought
end

def destroy
@thought = Opinion.find(params[:id]).like
registered_member.unlike!(@thought)
respond_with @thought
end
end

最后是表格thoughts/like_form

<div id="like_form">
<% if registered_member.liked?(@thought) %>
<%= render 'thoughts/unlike' %>
<% else %>
<%= render 'thoughts/like' %>
<% end %>
</div>

将呈现thoughts/unlike

<%= form_for(registered_member.opinions.find_by_like_id(@thought),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unlike", class: "btn btn-small btn-default" %>
<% end %>

或:thoughts/like

<%= form_for(registered_member.opinions.build(like_id: @thought.id),
remote: true) do |f| %>
<div><%= f.hidden_field :like_id %></div>
<%= f.submit "Like", class: "btn btn-small btn-primary" %>
<% end %>

opinions/create.js.erb结尾:

$("#like_form<%= @thought.id %>").html("<%= escape_javascript(render('shared/unlike')) %>")
$("#likes").html('<%= @thought.likes.count %>')

opinions/destroy.js.erb

$("#like_form<%= @thought.id %>").html("<%= escape_javascript(render('shared/like')) %>")
$("#likes").html('<%= @thought.likes.count %>')

请注意我为js做了一些可疑的事情......我试着说出类似的形式来定位一个特定的想法(成员的份额)。注意:这是迄今为止最成功的,但没有雪茄。它将fan_id(成员)和like_id(思想)添加到数据库并呈现不同的按钮。但它有不可预测的结果。例如:有时候,无论我喜欢哪个成员的共享,它总是会呈现与页面的第一个共享不同,尽管它会将正确的数据添加到数据库中。其他时候它会正常工作,但刷新页面后,它将呈现类似按钮(即使它当前被喜欢)或它将呈现正确的按钮,但它会在尝试“不同”共享时引发错误说“破坏/意见”没有匹配,表明它没有针对特定的份额。

所以重申一下我的故意问题:如果在成员的UNIQUE共享(class Opinion)中定义的分页列表中,我将如何“成功”呈现类似按钮(class Thought)为@share_items

很抱歉,如果我很困惑,第一次在这里发帖,我是Ruby新手。感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:0)

当你有嵌套对象时,你应该像这样声明你的表单:

form_for [@member, @opinion]

答案 1 :(得分:0)

我找到了一种方法,可以成功为会员的个人帖子呈现喜欢/不同的形式。虽然这是不可思议的,但是空间消耗最重要:缺乏趋势;它 工作。

我没有渲染like_form.html.erb,而是将代码直接添加到share_item.html.erb,并告诉表单不要寻找@thought,而是寻找share_item(这是嵌套在@share_items内的class Thought集合中的单个项目

thoughts/unlike.html.erb现在看起来像:

<%= form_for(registered_member.opinions.find_by_like_id(share_item),
html: { method: :delete },
remote: true) do |f| %>
<%= f.submit "Unlike", class: "btn btn-small btn-default" %>
<% end %>

thoughts/like.html.erb

<%= form_for(registered_member.opinions.build(like_id: share_item.id),
remote: true) do |f| %>
<div><%= f.hidden_field :like_id %></div>
<%= f.submit "Like", class: "btn btn-small btn-primary" %>
<% end %>

我可以从js中省略<%= @thought.id %>所以它看起来像("#like_form")

正如我所说的那样,我不得不在其中添加代码而不是将表单部分渲染,但如果我执行后者,则会收到“share_item是未知或未定义的局部变量”的错误。我已经完成了我的初始目标,让表单实际工作,我仍然在寻找关于如何呈现表单的建议,而不是直接将其添加到我的部分,而不会收到错误消息。