daveomcd
daveomcd

Reputation: 6565

Rails: How can I call a controller's create action without changing views?

I have a view, views/admin/index.html.erb, that has a button on it that I created with the following...

views/admin/index.html.erb

<%= button_to 'Manual Scrape', {:controller => "jobs", :action => "create", :job_type => "StatsAll"}, :method=>:post, :class => "btn btn-primary"  %>

controllers/jobs_controller.rb

  def create

    call_rake :import_records, :job_type => params[:job_type]
    flash[:notice] = "Import is executing..."

  end

controllers/application_controller.rb

  def call_rake(task, options = {})
    options[:rails_env] = Rails.env
    args = options.map { |n, v| "#{n.to_s.upcase}='#{v}'" }
    system "/usr/bin/rake #{task} #{args.join(' ')} --trace >> #{Rails.root}/log/rake.log &"
  end

When I click the button I would like it to remain on the current view which is, views/admin/index.html.erb, since I don't have a jobs view and don't believe I want one (maybe someone will convince me otherwise...). What I am trying to do is click the button and then on that view I will change the button to one that will call another action on the jobs_controller.rb to kill the job if necessary, otherwise it will execute until it completes.

However currently it tries to find the jobs view, which there is none. How can I correct this?

Note: I've used some of the code from Railscast #127 to see how to run a background task.

Upvotes: 0

Views: 2608

Answers (3)

jamby
jamby

Reputation: 606

You can always do this with some JavaScript/AJAX if you don't want to reload the page. First and foremost, I assume you have a path for your jobs controller for the jobs function? Find out by doing rake routes and see where your POST, not the GET for the create function in your jobs controller. I think you've made it this far to have it already there.

For your view, change it to:

<%= button_to 'Manual Scrape', jobs_create_path, :method=>:post, :remote => true, :class => "btn btn-primary"  %>

Your path may be different and want to take some kind of value, like the :job_type => "StatsAll" you had in there, but I'm not exactly sure.

You see that part for the :remote => true? That is where the special AJAX stuff happens. If you want something more complicated though, it can be (but it's a ton more work). But this is the easy way for it to start going to create.js.erb.

Make a create.js.erb in your app/views/jobs for the button where you can escape_javascript to rerender the button (like you said you wanted to do). After it rerenders, you can also do this same process for the other feature you wanted to include:

$('#create_button').html('<%= escape_javascript(render partial: "shared/create_job") %>'); // May need to use whatever locals you need to in here.

This should do it, since all it seems you want to do is just call a function and then stay on the page, but change the button.

Also, for the above code, this assumes you're using a partial for the button. This is so you don't have to completely re-render/reload the page, just the partial that corresponds with the button.

Upvotes: 1

Akash
Akash

Reputation: 5221

You can use the following for your create action.

def create    
  call_rake :import_records, :job_type => params[:job_type]
  redirect_to :back, notice: "Import is executing..."
end

Upvotes: 0

daveomcd
daveomcd

Reputation: 6565

So I've found that I can specify which page to go to by just doing a redirect_to at the end of the action. Like so...

  def create
    # Do stuf...
    redirect_to 'admin/#page-i-was-at'
  end

Upvotes: 0

Related Questions