1

I'm using eval to run some code (that is in a database, there are no ruby files) but this code requires some gems. How would I go about running the code? Maybe there's a better way than eval?

To give a bit more context, I have a toggle button in the view that switches a boolean to true or false in the model. This is possible for every "piece of code".

When it gets switched to true, the code starts running in a thread that never stops, and when it's switched to false this kills the thread.

I'm just trying to make the thread run the code right now.

I'm pretty new to rails so maybe there's a much better way than doing it by hand like what I'm doing, but I've tried googling some typical threading stuff and it's used for sending mail or other such things. Not for something that never stops unless told to (ie toggle the button that switches the boolean to false).

Thanks in advance.

1
  • You should include the code you are talking about. How do you call it? How do you use eval? Commented May 3, 2018 at 6:43

2 Answers 2

3

It sounds like you need the code to be prefixed with gem imports -- which probably requires a bundler environment to load those gems in the first place.

Since the code is stored in the database directly, you could prefix them with another column / constant that does all the gem loading for you.

If the gems are already installed via bundler on the server, try prefixing your code with bundle exec. To do this, you'll need to write the code to a temporary file location first.

To install the proper gems, that's part of your build/deploy processes.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the help. I'm still in development locally. I know eval is not good security wise, this is just for testing purposes as the application will be using another more secure way of doing it but I need to see if other stuff works doing it this simple but very unsecure way I admit. I will google prefixed gem imports but if you can give the example I'd be grateful ^^
@sokse stackoverflow.com/help/someone-answers also you may want to wait slightly longer before marking accepted on answers, especially the 1st one as someone else may subsequently offer a better answer.
bundle exec eval("...") – never seen that kind of invocation. Is the eval part supposed to be Ruby code or a shell function?
3

To run a script in the rails environment, which sounds like what you need, you can use rails runner. E.g. something like:

rails runner lib/scripts/my_script_to_run.rb 

This script would then get the required code from the database, and already have the correct (rails) context to be able to run the code.

Or maybe even more appropriate:

rails runner <your-ruby-code-here> 

See documentation

An alternative is to look at background-jobs, which seem imho a better fit to this problem. Check out the guides for ActiveJob : http://edgeguides.rubyonrails.org/active_job_basics.html

The advantage of using background-jobs:

  • it is a proven way of working
  • some adapters include extra managerial tools
  • you do not have to manage threads yourself
  • there is a clean way to describe jobs in code and queue jobs
  • using existing concepts/solutions is also easier to explain to other developers

There is a variety of adapters available and some of the easiest just store the jobs in the current database. For a full list see http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters.html, I would recommend starting with Que or DelayedJob. Your flow would change a little in that case: I would queue a job, and instead of looping, I would requeue as long as the toggle is not switched. But of course: I do not know your precise use-case so your approach could be equally valid or better.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.