Rails - 如何更新控制器中的单个属性

时间:2010-12-27 08:32:17

标签: ruby-on-rails activerecord

我是rails的新手并尝试完成一项简单的任务。我想在图像点击时切换布尔属性“完成”。 在我看来,我的链接如下:

<%= link_to image_tag("done.png"),
    feed_item,
    :controller => :calendars, :action=>:toggle_done,:id=> feed_item.id,
    :title => "Mark as done", :remote=> true, :class=>"delete-icon" %>

我添加了一条路线如下:

resources :calendars do
    get 'toggle_done', :on => :member
end

在控制器中,我创建了一个方法:

def toggle_done
    @calendar = Calendar.find(params[:id])
    toggle = !@calendar.done
@calendar.update_attributes(:done => toggle)

respond_to do |format|
  flash[:success] = "Calendar updated"
  format.html { redirect_to root_path }
  format.js
end

当我点击图片时,没有任何反应我看到以下错误:

Started GET "/toggle_done" for 127.0.0.1 at 2010-12-27 13:56:38 +0530
ActionController::RoutingError (No route matches "/toggle_done"):

我确信这里有一些非常微不足道的东西。

3 个答案:

答案 0 :(得分:8)

仅供参考,ActiveRecord提供“切换”和“切换!”完全按照名称在给定属性上声明的方法。

路线 - &gt;

resources :calendars do
  member do
    put :toggle_done
  end
end

查看(确保您使用正确的路径路径和正确的HTTP谓词)。根据RESTful架构,不应将GET用于更改数据库。 - &GT;

<%= link_to image_tag("done.png"), feed_item, toggle_done_calendars_path(feed_item)
    :title => "Mark as done", :remote=> true, :class=>"delete-icon", :method => :put %>

控制器 - &gt;

def toggle_done
  @calendar = Calendar.find(params[:id])
  @calendar.toggle!(:done)

  respond_to do |format|
    flash[:success] = "Calendar updated"
    format.html { redirect_to root_path }
    format.js
  end
end

答案 1 :(得分:2)

使用link_to时,您可以通过传递带有关联资源的Active Record模型或传递常规:controller / :action参数来指定URL。现在你传递了一个Active Record模型(feed_item)和:controller / :action参数,但是你只应该传递:controller / :action个参数情况下。

此外,当您传递URL哈希和其他HTML参数时,您需要在两个哈希周围包括括号,以便区分它们。

因此,请尝试以下方法:

<%= link_to image_tag("done.png"),
    { :controller => :calendars, :action =>:toggle_done, :id => feed_item.id },
    { :title => "Mark as done", :remote => true, :class =>"delete-icon" } %>

答案 2 :(得分:0)

解决问题的一些快速步骤是将:controller和:action移出link_to方法并进入路径,然后修复路线。

您的路线位于资源块内:日历。其中的每条路线都会在/日历/路径上匹配,因此此路线与/ toggle_done不匹配。这是一个匹配和路由/ toggle_done的简单路由:controller =&gt; :calendars,:action =&gt; :toggle_done

match :toggle_done => "calendars#toggle_done"

话虽如此,我建议使用RESTful路线。我猜你有日历资源,它有很多feed_items,我猜测toggle_done动作会在其中一个feed_items上更新完成的布尔值。应将更新映射为PUT请求。

resources :calendars do
  resources :feed_items do
    put :toggle_done, :on => member
  end
end

这将为您提供/ calendars / 1 / feed_items / 2 / toggle_done的路线,以便在日历1中的Feed_item 2上进行切换。