can't convert Symbol into String - ruby

I have the following code in Ruby, take directly from the Getting Started with Rails guide
def create
#post = Post.new(post_params)
#post.save
redirect_to #post
end
private
def post_params
params.require(:post).permit(:title, :text)
end
When I run the above Create I get the following error.
can't convert Symbol into string

It seems like you are trying to use strong paramaters. You get this error cannot convert symbol into string because you have not configured the strong_parameters. So by default you cant use require on params with symbols.
Configure strong parameters as follows:
1.) Add gem 'strong_parameters' to your gemfile and bundle it.
2.) Include Restrictions to you model as follows.
include ActiveModel::ForbiddenAttributesProtection to your model.
3.) Disable white listing in application confiuration(config/application.rb)
config.active_record.whitelist_attributes = false
See the documentation for more details on configuring.
Now your code should work.

If anyone is using Mongoid, you can fix this issue by adding the following to an initializer:
Mongoid::Document.send(:include, ActiveModel::ForbiddenAttributesProtection)

Add gem 'strong_parameters' to the gem file and
run >bundle install in command prompt
Refresh the browser.

Related

Monkey-patch using modules in a gem

I'm building a Ruby gem that includes a module that's meant to monkey-patch the Hash class to add a new method. I'm following this guide to try to do it neatly: http://www.justinweiss.com/articles/3-ways-to-monkey-patch-without-making-a-mess/
I've placed the module in lib/core_extensions/hash/prune.rb, and the module is declared as such:
module CoreExtensions
module Hash
module Prune
##
# Removes all pairs from the Hash for which the value is nil. Destructive!
def prune!
self.reject! { |_, v| v.nil? }
end
end
end
end
And in order to make the monkey patch take effect, I'm calling this within the main gem file:
Hash.include(CoreExtensions::Hash::Prune)
But after building the gem and trying to require it in an irb console, I get the following error: NameError: uninitialized constant Gem::CoreExtensions (Gem is a placeholder name).
I made sure to include the prune.rb file in my gemspec's files array: s.files = ['lib/gem.rb', 'lib/core_extensions/hash/prune.rb'], so I'm not sure why it can't detect the file and its modules. Can anyone help me figure this out?
Thank you!
EDIT: In case it will help anyone else - I tried to require the module file using require 'lib/core_extensions/hash/prune' but received 'cannot load such file' errors. Sticking ./ in front of the path fixed it.

Using File::read in a provider's default.rb in Chef

I am trying to create an LWRP that will call the resource that is defined within itself. My cookbook's structure is as follows:
In the machine cookbook's provider, I have a code snippet as follows:
require 'chef/provisioning' # driver for creating machines
require '::File'
def get_environment_json
##environment_template = JSON.parse(File::read(new_resource.template_path + "environment.json"))
return ##environment_template
end
The code is only trying to read a json file and I am using File::read for it.
I keep getting an error as follows:
LoadError
cannot load such file -- ::File
Does anyone know how I can use File::read inside my LWRP's provider?
OK, so the prior two answers are both half right. You have two problems.
First, you can't require ::File as it's already part of Ruby. This is the cause of your error.
Second, if you call File.read you will grab Chef's File not ruby's. You need to do a ::File.read to use Ruby's File class.
require '::File'
Is incorrect and is causing the LoadError. Delete this line. You don't need it. File is part of the Ruby core and doesn't need to be required.
To further explain, the string argument to require represents the file name of the library you want to load. So, it should look like require "file", or require "rack/utils".
It happens becuase Chef already has a file resource. We have to use the Ruby File class in a recipe.We use ::File to use the Ruby File class to fix this issue. For example:
execute 'apt-get-update' do
command 'apt-get update'
ignore_failure true
only_if { apt_installed? }
not_if { ::File.exist?('/var/lib/apt/periodic/update-success-stamp') }
end
Source: https://docs.chef.io/ruby.html#ruby-class

Padrino Tutorial: Can't Modify Frozen String (Runtime Error)

I am following the Padrino tutorial from here:
https://www.padrinorb.com/guides/blog-tutorial
I am copy and pasting the commands but I quickly ran into an error I don't understand:
$ padrino g controller posts get:index get:show
create app/controllers/posts.rb
create app/views/posts
apply tests/shoulda
/Users/waprin/.rvm/gems/ruby-2.1.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators/controller.rb:66:in `prepend': can't modify frozen String (RuntimeError)
from /Users/waprin/.rvm/gems/ruby-2.1.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators/controller.rb:66:in `create_controller'
This might be a bit late, but in case anyone else runs across this error (and because I just worked through the same tutorial) I'll post anyway...
It looks like there's an issue when generating controllers if a test component is specified. In this case you're using shoulda, but the same happens when using rspec and maybe others. It's been reported as a bug: https://github.com/padrino/padrino-framework/issues/1850 and has been fixed, but isn't yet part of a stable release.
One option to fix this would be to change your Gemfile to work with the latest from their github repo. To do this delete your GemFile.lock file, and comment out the line under 'Padrino Stable Gem' in your GemFile:
gem 'padrino', '0.12.4'
then uncomment the line under 'Or Padrino Edge':
gem 'padrino', :github => 'padrino/padrino-framework'
then re-run bundle install.
Of course, you'll no longer be running the stable release, and that may come with other trade-offs.
As a side-note, I believe that the guide on that page is fairly out of date. I also needed to replace:
get :index do
#posts = Post.all(:order => 'created_at desc')
render 'posts/index'
end
with:
get :index, :provides => [:html, :rss, :atom] do
#posts = Post.order('created_at desc')
render 'posts/index'
end
in the Post controller as the active record interface has changed since the time that the guide was written.
I was able to sole this problem by simply going to padrino gem path.
For me it was:
/Users/ahmadhassan/.rvm/gems/ruby-2.2.0/gems/padrino-gen-0.12.4/lib/padrino-gen/generators
open controller.rb and change line number 61:
path = #controller
to
path = #controller.dup

Ruby script, best method to store login information for an API?

I'm currently working on a script (command line tool) for work to help me manage expose consoles.
At first I was passing three arguments to the script each time I used it to login into the consoles, for example:
$ nexose-magic.rb -u user -p password -i 192.168.1.2 --display-scans
It's not very efficient, so I created a config.yml file that stores console information in a hash.
$ nexpose-magic.rb -c console --display-scans
I believe the tool will be useful to admins out there, so I'd like to share it in a gem. I can't figure out how to get my config.yml file to work with a gem install..It can't find the config.yml file! It's easy to point it at the relative path in my development directory, but once I create a gem that relative path isn't so relative anymore. How do I point nexpose-magic.rb at the config.yml file?
Is there a better way to handle something like this?
You can create a gem that include a configure class. This class has a load method that will take a directory as an argument. Then, you can pass the directory where you are currently working.
A nice way of preparing your gem is to create a Configuration singleton class in your gem:
require 'singleton'
class Configuration
include Singleton
attr_accessor :config, :app_path
def load(app_path)
#app_path = app_path
#load the config file and store the data
#config = YAML.load_file( File.join(#app_path,'config','config.yml'))
end
end
In your main class :
module MyFancyGem
class << self
#define a class method that configure the gem
def configure(app_path)
# Call load method with given path
config.load(app_path)
end
# MyFancyGem.config will refer to the singleton Configuration class
def config
MyFancyGem::Configuration.instance
end
end
end
Usage:
-Working directory
- my_new_script
- Gemfile
- config/
- config.yml
In my_new_script :
require 'bundler'
Bundler.setup(:default)
require 'my_fancy_gem'
MyFancyGem.configure(File.join(File.dirname(__FILE__),"./")) #here, you define the path
MyFancyGem.hello_world
I hope that's clear enough. I was actually about to write a blog post to explain this particular point (I hope in a more complete version of it). Let me know if you're interested !

How do I change the aws-ruby log location?

I've found the method set_log in the documentation, I just can't figure out the syntax to call it. Here's what I tried:
require 'ruby-aws'
Amazon::Util::Logging.set_log('my.log')
NoMethodError: undefined method `set_log' for Amazon::Util::Logging:Module
You can see that Amazon::Util::Logging is a module and set_log is a 'Public Instance method'. So you need
class NewClass
include Amazon::Util::Logging
def foo
set_log('file.txt')
log 'debug_message'
end
end
I ran into this problem when trying to deploy a Ruby-on-Rails site that uses 'aws-ruby' to heroku (I got the "Permission denied - ruby-aws.log" error).
To change the log file location from 'ruby-aws.log' to 'log/ruby-aws.log', I added the following to an initializer. Make sure this is called before you use any of the aws-ruby library. Notice the change on the "set_log..." line.
module Amazon
module Util
module Logging
def log( str )
set_log 'log/ruby-aws.log' if ##AmazonLogger.nil?
##AmazonLogger.debug str
end
end
end
end
A simpler way would be to add this line:
set_log("/dev/null")

Resources