2011-04-16 56 views
0

要教自己的Rails,即时通讯构建一个非常简单的投票应用程序。在rails 3中投票应用程序:我如何链接到投票方法?

有2个型号,问题和选项。问题has_many选项和选项belongs_to问题。

使用标准的脚手架,我已经到了一个阶段,您可以添加一个问题,查看它,并添加选项,并看到这些选项。

我现在想要做的是添加代码,当点击一个链接时增加一个option.count的值。我在期权模型vote_up方法:

class Option < ActiveRecord::Base 
    validates :text, :presence => :true 
    belongs_to :question 

    def vote_up 
    self.count += 1 
    end 
end 

我的选项控制器看起来像:

class OptionsController < ApplicationController 
    def create 
    @question = Question.find(params[:question_id]) 
    @option = @question.options.create(params[:option]) 
    redirect_to question_path(@question) 
    end 

end 

我的问题模型是这样的:

class Question < ActiveRecord::Base 
    validates :text, :presence => {:message => 'A question normally has text...'} 
    has_many :options, :dependent => :destroy 


    def vote 
    # Maybe the vote code will go here??? 
    end 
end 

我的问题控制器具有通常的新的,创建,编辑,销毁脚手架创建的方法。 V在这里很少定制。

我show.html.erb看法,我想放的链接投票方法是这样的:

<p id="notice"><%= notice %></p> 
    <p> 
     <b>Question <%= @question.guid %></b>: 
     <%= @question.text %> 
    </p> 
    <% if @question.options.count == 0 %> 
     <p>Shame! there are currently no options to vote on. Add some! </p> 
    <% elsif @question.options.count == 1 %> 
     <p>One option in a vote is a dictatorship... Maybe add some more?</p> 
    <% end %> 
    <h2>Options:</h2> 
    <% @question.options.each do |option| %> 
     <p> 
     <%= option.text %>: ** Link to vote here! 
     </p> 
    <% end %> 

    <h2>Add an option to vote on</h2> 
    <%= form_for([@question, @question.options.build]) do |f| %> 
     <div class="field"> 
     <%= f.label :text %><br /> 
     <%= f.text_field :text %> 
     </div> 
     <div class="actions"> 
     <%= f.submit %> 
     </div> 
    <% end %> 

    <% if @question.options.count == 0 # Only show edit if no options saved. %> 
     <%= link_to 'Edit', edit_question_path(@question) %> | 
    <% end %> 
    <%= link_to 'Back', questions_path %> 

那么什么,我试图做的是增加一个“投票”旁边的链接各选项,它在选项模型中调用了vote_up方法。这可能很容易,但我已经打了一堵墙,非常感谢任何帮助。

此外,如何更好地做到这一点的任何建议将受到欢迎!

感谢

西蒙

回答

1

我认为@ oded-harth已经展示了一个正确的方式,但我有两个备注:

首先,Rails是一门美丽的语言,它的写作旨在简化开发人员的生活;)在Rails编程时,您绝对不能忘记这一点。考虑到这一点,我想指出你"increment()" method。所以你可以简单地投票而不用不必要的+= 1。使用decrement()降票。我相信你可以这样使用它:option.increment(:count)

其次,我认为有一个简单的投票行动的整个form有点肮脏。您可以使用类似这样

<%= link_to "Vote Up", :url => { :action => :vote_up, :option_id => option.id }, :method => :put %> 

要使其工作,你必须设置你的路线是这样的:

resources :votes 
    put :vote_up 
end 
+0

感谢您的支持。越来越近。现在,当我点击投票链接时,我将采取http:// localhost:3000/questions/9?method = put&url [action] = vote_up&url [option_id] = 1这是当前带有params参数的页面.....另外,你的意思是资源:选项,而不是资源:票?我已经把vote_up方法放在了问题控制器中。再次感谢! – Simon 2011-04-17 17:41:42

+1

我忘记提及,如果您在项目中使用Javascript库(例如jQuery-UJS),或者默认包含在“public/javascripts”中的rails项目中的Scriptaculous和Prototype,此方法就可以工作。 您可能还需要定义继承路线: '资源:问题做 资源:选择做#是我的意思是选择;) 放:vote_up 放:vote_down 结束 end' 再看看到你的路线与'rake routes'并找到'PUT questions /:question_id/options /:id/vote_up'。然后使用它的URL方法,而不是':url => {...}' – Ivan 2011-04-18 09:06:12

+0

顺便说一句,'vote_up'方法进入'OptionsController',因为你正在通过增加/减少值'1'来改变'Option'模型。 – Ivan 2011-04-18 09:10:17

0

我会做的是使vote_up方法控制器:

def vote_up 

option = Option.find(params[:option_id]) 
option.count += 1 

redirect (to where do you want...) 

end 

并在视图我会调用该方法是这样的:

<%= form_for(option, :url => { :action => "vote_up", :option_id => option.id}) do |f| %> 
<%= f.submit("vote up") %> 
<% end %> 
+0

感谢。只是为了澄清 - 你的意思是在选项控制器? – Simon 2011-04-16 11:29:07

+0

是的,但它也可以在问题控制器中工作。 – 2011-04-16 13:06:01