Ruby on Rails 的投票更新

发布于 2024-09-17 19:29:59 字数 856 浏览 6 评论 0原文

现在,我正在 Ruby on Rails 上构建一个社交媒体应用程序,我已经实现了 5 点投票系统。您可以在 1-5 点对网站上发布的新闻进行投票,我想知道的是,处理投票系统更新的最佳方法是什么。

在例子中。如果用户已经在一篇文章中投票,我想取回他在文章中给出的分数并软锁定投票(因为我只允许每个用户 1 票,并且我允许随时更改您的投票),但是如果他还没有,我将提出投票为 0 的文章。

我知道一种方法来完成此操作,我可以在视图中执行此操作,并检查当前用户是否已经对这篇文章进行了投票,我将发送给他们到编辑视图,否则到显示视图。 (我认为)

无论如何,“正确”的方法是什么?

编辑:我忘了说投票组合框是我正在渲染的一部分。我是否应该以某种方式更新部分内容?

编辑2:

class Article < ActiveRecord::Base

  has_many :votes
  belongs_to :user

  named_scope :voted_by, lambda {|user| {:joins => :votes, :conditions => ["votes.user_id = ?",  user]}  }
end

class User < ActiveRecord::Base
  has_many :articles
  has_many :votes, :dependent => :destroy

  def can_vote_on?(article)
    Article.voted_by(current_user).include?(article) #Article.voted_by(@user).include?(article)
  end

end

Right now, I'm in the middle of building a social media app on Ruby on Rails, i have implemented a 5 point voting system. Where you can vote the news posted on the site from 1-5, what I'd like to know is, What is the best approach at handling the updates on the voting system.

In example. If a user already voted in an article I'd like to bring back score he gave in the article and soft-lock the voting (since i only allow 1 vote per user and i allow to change your vote at any time), but if he hasn't I'll bring up the article with the the voting on 0.

I know a way to accomplish this, i could do it in the view, and check if the current user has already voted on this article i would send them to the EDIT view otherwise to the SHOW view. (I think)

Anyways, what would be the "correct" approach to do this?

EDIT: I forgot to say that the voting combo box it's a partial that I'm rendering. Am i suppose to just update the partial somehow?

EDIT2:

class Article < ActiveRecord::Base

  has_many :votes
  belongs_to :user

  named_scope :voted_by, lambda {|user| {:joins => :votes, :conditions => ["votes.user_id = ?",  user]}  }
end

class User < ActiveRecord::Base
  has_many :articles
  has_many :votes, :dependent => :destroy

  def can_vote_on?(article)
    Article.voted_by(current_user).include?(article) #Article.voted_by(@user).include?(article)
  end

end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掩耳倾听 2024-09-24 19:29:59

在 User 模型中创建一个方法,如果用户可以对文章投票,则响应 true

class User < ActiveRecord::Base

...

def can_vote_on?(article)
  articles_voted_on.include?(article) # left as an exercise for the reader...
end

end

在视图中,如果用户可以编辑,则呈现一个表单,否则呈现一个普通视图:

<% if @user.can_vote_on?(@article) %>
  <%= render :partial => "vote_form" %>
<% else %>
  <%= render :partial => "vote_display" %>
<% end %>

或者您可以处理整个事情都在控制器中,并为表单版本和普通版本呈现单独的模板。最佳方法取决于您的具体情况。

EDIT2

正如您所发现的,current_user 在模型中不起作用。这是有道理的,因为可以从迁移、库等中调用,而这些地方没有会话的概念。

无论如何,都不需要访问当前用户,因为您的实例方法(根据定义)是在实例上调用的。只需引用模型中的 self,并从 current_user 的视图中调用方法,它是 User 的实例:(

在模型中)

  def can_vote_on?(article)
    Article.voted_by(self).include?(article)
  end

(在视图中)

<% if current_user.can_vote_on?(@article) %>

或者如果控制器分配了它,您可以用 @user 替换 current_user

最后一件事,我认为您的命名范围应该使用 user.id,如下所示:

named_scope :voted_by, lambda {|user| {:joins => :votes, :conditions => ["votes.user_id = ?",  user.id]}  }

Create a method in the User model that responds true if the user can vote on an article:

class User < ActiveRecord::Base

...

def can_vote_on?(article)
  articles_voted_on.include?(article) # left as an exercise for the reader...
end

end

In the view, render a form if the user can edit, otherwise render a normal view:

<% if @user.can_vote_on?(@article) %>
  <%= render :partial => "vote_form" %>
<% else %>
  <%= render :partial => "vote_display" %>
<% end %>

Or you could handle the whole thing in the controller, and render separate templates for the form version and the normal version. The best approach depends on the specifics of your situation.

EDIT2

As you discovered, current_user doesn't work in the model. This makes sense, because the can be called from migrations, libraries, etc., where there is no concept of a session.

There's no need to access the current user anyway, since your instance method is (by definition) being called on an instance. Just refer to self in the model, and call the method from the view on current_user, which is an instance of User:

(in the model)

  def can_vote_on?(article)
    Article.voted_by(self).include?(article)
  end

(in the view)

<% if current_user.can_vote_on?(@article) %>

Or you could substitute @user for current_user if the controller assigns it.

One last thing, I think your named scope should use user.id, like so:

named_scope :voted_by, lambda {|user| {:joins => :votes, :conditions => ["votes.user_id = ?",  user.id]}  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文