【问题标题】:query in rails3在rails3中查询
【发布时间】:2011-04-05 10:49:10
【问题描述】:

在我最近提出的另一个问题中,我得到了一个非常好的答案并且代码有效...但我不知道它为什么有效...现在我有一个类似的问题,但不知道如何解决它...?

我有什么:

型号

users
questions (with answer_id)
answers
votes (with answer_id and user_id)

用户模型:

has_many :questions
has_many :votes
def can_vote_on? (question)
    !question.answers.joins(:votes).where('votes.user_id = ?', id).exists?
  end

def voted_answer? (question)
   (what to do here...?) 
  end

问题模型:

belongs_to :user
has_many :answers, :dependent => :destroy
accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:text].blank? }, :allow_destroy => true

答案模型:

belongs_to :question
has_many :users, :through => :votes, :dependent => :destroy
has_many :votes

投票模型:

belongs_to :answer
belongs_to :user

在我的问题视图中,当 current_used 对该特定答案进行投票时,我想将文本加粗。那么我该如何完成这个:

<% for answer in @question.answers %>
 <% if current_user.voted_answer? (@question) %>
  <td>
   <strong><%= answer.text %></strong> 
  </td> 
 <% else %>
  <td>
   <%= answer.text %>
  </td> 
 <% end %>
<% end %>

提斯

【问题讨论】:

    标签: ruby ruby-on-rails-3 rails-models


    【解决方案1】:

    你可以这样做

    <% for answer in @question.answers %>
      <% if answer.votes.index{|vote| vote.user_id == current_user.id} %>
        <td>
        <strong><%= answer.text %></strong> 
        </td> 
      <% else %>
        <td>
        <%= answer.text %>
        </td> 
      <% end %>
    <% end %>
    

    更新

    更多逻辑变体创建 voted_by_user?类Answer中的函数

    class Answer
      def voted_by_user?(user)
        voits.where('votes.user_id = ?', user.id).exists?
      end
    end
    
    <% @question.answers.each do |answer| %>
      <td>
        <% if answer.voted_by_user?(current_user) %>
          <strong><%= answer.text %></strong> 
        <% else %>
          <%= answer.text %>
        <% end %>
      </td> 
    <% end %>
    

    【讨论】:

    • 哇,它奏效了 voits 需要投票......但你能解释一下它为什么有效吗??
    • 好的,我明白了!您正在将 vote.id 与 vote.user_id 中的 answer_id 进行比较
    • 答案包含 voits。 voits 推荐用户。如果 current_user.id == voit.user_id - 这意味着该用户为这个答案投票
    • 此代码不起作用,OP 没有定义模型或方法voits
    【解决方案2】:

    听起来你只是想要can_vote_on? 的相反结果,即如果用户不能对答案投票(can_vote_on? 返回 false),那么这意味着他们已经投票了(voted_answer? 应该在此返回 true情况),反之亦然。

    解决这个问题的一种方法是让voted_answer? 返回can_vote_on 的否定:

    def voted_answer? (question)
        !can_vote_on? question
    end
    

    当然,您也可以使用您在can_vote_on? 中使用的查询而无需否定:

    def voted_answer? (question)
        question.answers.joins(:votes).where('votes.user_id = ?', id).exists?
    end
    

    但由于 DRY 原则,我更喜欢第一种解决方案。

    更新

    我对否定的看法是错误的。在这种情况下,您正在处理一个特定的答案,而不是所有答案。

    在您的模型中,您需要以下内容:

    def voted_answer? (answer)
        answer.votes.where('votes.user_id = ?', id).exists?
    end
    

    【讨论】:

    • 谢谢,但它不起作用......现在我得到所有结果粗体,因为查询检查是否存在任何 votes.user_id......我只知道 current_user.id 投票回答...
    • @Thijs - 明白了,我不确定 id 在那个电话中来自哪里。在我展示的第二个示例中,您是否尝试过用 current_user.id 替换 id ?我认为can_vote_on? 也在使用当前用户的 id。
    • 我尝试了什么,但我总是得到未定义的方法错误:def voted_on? (问题) question.answers.joins(:votes).where('votes.user_id = ?', current_user.id) end
    • 是的 answer 没有在问题上定义,answers 是。您想从 for 循环中传入 answer,请不要使用 @question&lt;% if current_user.voted_answer? (answer) %&gt;
    • @Thijs - 没问题,我很高兴它成功了。因此,在您看来,您正在遍历所有问题的答案。然后,您将每个答案传递给voted_answer?。此方法接受 answer 参数并获得其投票(通过 db 查询),然后使用 current_user 的 id 查找对该答案的任何投票。您可以简单地调用“id”,因为它是可通过任何对象获得的方法,并且由于您在 current_user 上调用 voted_answer?,因此您正在检查 current_user 的 id。如果在给定 current_user 的情况下存在对该答案的投票,那么您就知道该答案是被选中的。
    猜你喜欢
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    相关资源
    最近更新 更多