Shell command not executed by rails action - ruby-on-rails

I'm pretty new to ruby and ruby on rails so please pardon me if this might sound very trivial to you.
I want to run a shell command on button click from my rails application. I've created required view and action, and also updated my routes.rb file to post to the required view. I also have defined a function in my model, which will finally be executing the shell command. Everything runs smoothly, with the workflow going as planned, but the command is not executed. Also, the app shows no error. Following are the snippets of my respective model, action and controller. I'am using Rails 4.1.1, with Ruby-2.1.2, on a Ubuntu 12.04 LTS.
Here is my routes file. I have overwritten the default /post route from directory#create to 'directory#create_directory'.
Rails.application.routes.draw do
match '/directories', to: 'directories#create_directory', via: 'post'
resources :directories
Model : The command i want to execute is specified in this function.
class Directory < ActiveRecord::Base
def self.create_directory
`mkdir dummy_dir`
end
end
Custom controller-action
def create_directory
#directory = Directory.create_directory
end
New directory view(generated using scaffolding)- This is the page where we land from the index page, after we click on create a new directory option. I've added a button_to, clicking on which redirects me to my custom action create_directory.
<h1>New Directory</h1>
<%= button_to "Create Directory",
url_for( :action => "create_directory", :controller=> :directories ),:remote=>true %>
<%= link_to 'Back', directories_path %>
I also have created a dummy view for create_directory action. I land on this view in the end.
Well, everything runs smoothly without giving any error, but the directory is not created. Any suggestions as to where i might be going wrong.
Thanks in advance

Related

How do I execute a Ruby command when a link_to is pressed?

Basically, what I want to do is run a FactoryGirl.create whenever a link_to is pressed.
Right now, every time I want to generate a new object in my DB, I have to go into Rails Console and type: FactoryGirl.create(:object).
But, ideally...I would love to be able to execute that from the link_to.
Not sure how to do that though.
Thoughts?
I suppose you could treat the creation of an object via FactoryGirl like any other RESTful resource with a dedicated controller and routes:
class MyFactoryGirlController
def create
if FactoryGirl.create(:object)
# Do something
end
end
end
routes.rb
post '/someroute', to: 'myfactorygirl#create', as: :factory_girl
And your link:
link_to "Create an object", factory_girl_path(object: 'SomeObject'), method: :post
Note that this code is meant to illustrate a concept and is incomplete. Copy and pasting will not work.

Rails 4 + Devise + Routing Error

I'm attempting to install Devise on a rather simple event creating/displaying Rails 4 app. I have 2 static pages and the index page displaying without authentication, and all is well there. Anything else kicks you to the "sign up" page. From there, when I attempt to create an account for myself (to simply see the other pages- simple vanilla devise installation attempt) I get a "No route matches [POST] "/registrations/user" error when clicking "submit" (f.submit)
I am using Rails 4, have the 3.0.3 version of Devise, bundled it, ran "rails generate devise:install" to install it, ran "rails generate devise user", ran db:migrate, raked the routes, and restarted the Rails server.
I even recreated the button action with the "correct" route and "get post" - no dice.
Anybody have any idea? I'm at a loss here.
Well it's always tricking debugging sever-side code without seeing it in action, but here's what should work.
yourappname/config/routes.rb :
devise_scope :user do
# matches the url '/register' to the registration controller's 'new' action and creates a :register symbol inorder to reference the link dynamically in the rest of the code
get 'register', to: 'devise/registrations#new', as: :register
end
(Assuming your register button is in your app's partial)
yourappname/app/views/layouts/application.html.erb:
<%= link_to "Register", register_path, class: "btn" %>
Now you could actually put that link_to anywhere, in any page, and it'll work. The reason for this is the 'register_path'.
When you create your route, the as: :register parameter creates a global variable that can be accessed throughout your app.
the register_path variable in your link_to method will always call the right action, even if you change your routes file.
It's just syntax. You could create any symbol you want. This would also work:
routes.rb:
# Inside get method, third parameter
as: :bowtiesarecool
someview.html.erb:
# Inside link_to method, second parameter
bowtiesarecool_path
Just match the variable name with the symbol name and a put a _path after it. The link_to method will handle everything else!

link_to custom action but wrong method?

all, I'm trying to get a custom action to work with a put method: in the
in _post.html.erb i have a link_to statement:
<%= link_to 'End now', post, :method => :put, :action => endnow %>
routes.rb contains:
resources :posts do
member do
put :endnow
end
and posts_controller.rb looks like:
class PostsController < ApplicationController
helper_method :endnow
[.. code for create, edit, destroy, etc ..]
def endnow
puts params
end
end
rake routes's relevant line looks like:
endnow_post PUT /posts/:id/endnow(.:format) posts#endnow
However, the action endnow helper doesn't run when clicking on this link.
Strangely, it does run with an index action (which i can tell from the puts command.
Of course, eventually the code for endnow will update #post, but for now, it just doesn't run properly.
Maybe i'm going about this the wrong way - all I'm trying to achieve is to update #post upon clicking the link to that post, and before showing it.
Any ideas / Alternatives?
Why not use the route helper method provided to you? Change your link to
<%= link_to 'End now', endnow_post_path(#post), method: :put %>
Things you're doing wrong:
If you want to specify the :action, use the Symbol for the action (you're missing a colon). :action => endnow should be action: :endnow
I will assume you have a #post instance variable you're passing from your controller to your action. You should be using that instead of post (unless you do in fact have a local post variable you're omitting from your code)
You are using endnow as an action; you should remove the helper_method :endnow line in your controller because it's not something you want to/should be accessing from your view.
This can all be avoided by using the route helper (for endnow_post you'd append _path to get the local route path: endnow_post_path), and pass in your #post as an argument.
Because you're trying to do a PUT request, you must make sure you have something like jquery-ujs included in your asset pipeline to convert these links to form submissions behind the scenes; browsers don't support PUT via the click of a link on their own.
As for why you're getting the template error when you get your link_to working, Rails is telling you that you need to create a app/views/posts/endnow.html.erb file. Your action has only puts params which does not terminate execution, leaving Rails to assume you still are trying to render some endnow.html.erb template.
Are there other ways to do what you're trying to do (change a single attribute of a specific model)? Sure. Are there better ways? That's pretty subjective; it may not be the most RESTful way, but it's arguably easier to deal with (if for example there are very specific authorization rules to check before updating the attribute you are modifying in endnow. Does the way you've started fleshing out work? Absolutely.
Finally, as a bump in the right direction, after you fix your link_to and remove the the helper_method as I have described above, your endnow action might look like this:
def endnow
post = Post.find!(params[:id])
post.some_attribute_here = some_new_value_here
post.save
redirect_to :root and return # <- this line sets a redirect back to your homepage and terminates execution, telling rails to do the redirect and **not** to render some endnow.html.erb file
end

Rails - link to new action instead of show if an item doesn't exist?

I'm trying to create a link so that if the current user has a project already created, then they just click the 'Project' link, and it will take them to their project. Each user can only have one project. If they don't have a project, then it will instead take them to the form to create one (i.e. the new view/action).
How would I go about this? I apologise, I'm new to rails. At the moment, I am using the following:
<%= link_to 'Project', project_path %>
which works fine if the user already has a project, but says "No route matches {:action=>"show", :controller=>"projects"}" if one doesn't exist. I'm not sure where to start - do I add in conditions to the link_to, or is it something I need to put in the controller? Thanks!
I guess you should check it inside the new action. Find project if exist and redirect to the edit action.
If you will decide which link to render user can cheat you and type /projects/new in address bar.
<%= link_to 'Project',
current_user.project.present? ?
project_path(current_user.project) :
new_project_path %>

Submit form without using object

It's my first post on stackoverflow! I warn you, I just started learning Ruby on Rails.
Currently, I'm working on a music scanning project in rails. I'm trying to process al the music on the hard disk. To do that, the user can add a folder to scan when he is inside the config part of the app. So I store inside a YAML file all the config of my app.
I create a 'config' controller, that contains 2 view for the moment: "adddir" and "index".
The index view show all parameters, that have been gathered by loading the YAML config file (done by the controller 'config').
Next, I want to give the possibility to the user to add a new folder to scan. So I did a static route to the 'adddir' view:
routes.rb file:
match "/config/adddir" => "config#adddir"
Now, I want to create a form that get the path provided by the user, and add it to the YAML file.
So my question is: How to create a form that be able to use the method config#addfolder I created when the user click on submit button?
I hope this is enough clear.
Best regards
Welcome to SO. Its a very basic question. Just have a look at the screencast. Make a simple project first (with a model), then you will see the ABC of Rails.
http://rubyonrails.org/screencasts/rails3/
Basically:
You generate the controller like:
rails g controller config adddir
This setups the controller, the view and your route.
Then go into your view folder and look inside config. There is adddir.html.erb. This file you need to change in something like a form.
You can open your form:
http://localhost:3000/config/adddir
rake routes
Will print you a list of available routes you can use (inside your form).
Now the magic is that Rails generate your a config_adddir_path (watch the _path). That you can use to hookup the form.
<%= form_tag(config_adddir_path, :method => "get") do %>
<%= label_tag(:q, "Folder:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("index") %>
<% end %>
Inside your controller (def adddir):
You can access the parameters:
def adddir
logger.debug params.inspect
end
Have a look here:
http://guides.rubyonrails.org/form_helpers.html

Resources