Rails 3: How to execute rake task with form submit button
I would like the submit button action to execute a rails method or a rake task on the server side. The task copies the records from one model to another. I intend to add the button to the bottom of the index view of the pages controller.
I've read some posts but still can't figure out how to use the remote_function. Also tried using :onclick => :make_assets but nothing happens. Thanks
e.g. radio_button :model, :method, :onclick => remote_function(:controller => 'some', :a开发者_JS百科ction => 'action')
lib/tasks/move_photo.rake
namespace :db do
desc "Move records from photos to assets" task :movephoto => :environment do Rake::Task['db:migrate'].invoke make_assets end end def make_assets Photo.all.each do |photo| newasset = nil newasset = Asset.create!(:user_id => photo.user_id, :image => photo.image) photo.destroy unless newasset.nil? end end/app/controllers/photos_controller.rb
def make_assets
Photo.all.each do |photo| newasset = nil newasset = Asset.create!(:user_id => photo.user_id, :image => photo.image) photo.destroy unless newasset.nil? end end/app/views/photos/index.html.erb
<%= will_paginate %>
<%= will_paginate %>
<%= submit_tag 'Approve', :onclick => remote_function(:controller => :photos, :action => :make_assets) %>Executing a rake task from the controller is an exceedingly bad idea.
Never give an untrusted client access to your system.
That said, it seems like what you really want to do is something that fits well within the parameters of a controller action. I think you're missing the :url
hash in the remote function call:
<%= submit_tag 'Approve', :onclick => remote_function(:url => {:controller => :pages, :action => :make_assets}) %>
you can run a rake command, its like running a dos or shell command from rails.But as I can see you want run rake db:migrate and then some other task and as per my understading of rails, you need to restart the application after running such rake tasks so that would make a problem if you are running rake command for current running application.
For other stuff i.e. copy records from one model to another, you can have a class method in Model(Photo model in your case) and can invoke that method in controller's action which invoked from UI. The code might look as
photo Model
class Photo < ActiveRecord::Base
def self.make_assets
Photo.all.each do |photo|
newasset = nil
newasset = Asset.create!(:user_id => photo.user_id,
:image => photo.image)
photo.destroy unless newasset.nil?
end
end
end
photo controller
def make_assets
Photo.make_assets
end
view side you have various option to invoke make_assets action
1) link_to
<%= link_to "Make Assets",
url_for( :action => "make_assets", :controller=> :photos ),:remote=>true %>
2) button_to
<%= button_to "Make Assets",
url_for( :action => "make_assets", :controller=> :photos ),:remote=>true %>
3) form_tag
<% form_tag(:url => url_for(:action => "make_assets", :controller=> :photos),:remote => true) do -%>
<div><%= submit_tag 'Save' %></div>
<% end -%>
Yeah, rake tasks are not intended to be run from a controller. Consider refactoring and extracting take task functionality to separate method. Then you can call this method both from the rake task and the controller action.
To be honest, i wanted to debug my rake task this way before realizing the need to to refactor.
As for your code to work you have to load tasks manually, and don't forget to reenable the task in order to run it second time.
require 'rake'
Rake::Task.clear # necessary to avoid tasks being loaded several times in dev mode
Sample::Application.load_tasks # providing your application name is 'sample'
class RakeController < ApplicationController
def run
Rake::Task[params[:task]].reenable # in case you're going to invoke the same task second time.
Rake::Task[params[:task]].invoke
end
end
You can require 'rake' and .load_tasks in the initialization section.
You can try with the button_to
helper for calling the controller action:
<%= button_to 'Approve', :controller => :pages, :action => :make_assets %>
add the remote => true
parameter if you want to do the request via Ajax
精彩评论