0

I am working on a webapp that contains the basic elements of a CMS webapp. Users can clone the repo, run the rails server, and be taken to a page that allows them to rename the app from the current name, "framework", to whatever they want. After a bit of debate here, I decided to put the renaming code into my controller (as opposed to in a rake file). But my problem is that my controller has trouble figuring out what's going on. This is what my view looks like.

<h1>Rails Framework</h1>

<%= form_tag "/namer" do %>
  <%= text_field_tag "appname" %>
  <%= submit_tag "Name Your App" ,  :action => 'create' %>

<% end %>

And this is my controller.

class NamerController < ApplicationController

  def index
    render('new') 
  end  

  def new
    @appname = Namer.new
  end

  def create
    @appname = Namer.new(params[:appname])
    #first, change any instances of the term "framework" to the new name of the app   
    file_names = ['config/environments/test.rb', 'config/environments/production.rb', 
      'config/environment.rb']
    file_names.each do |file_name|
      text = File.read(file_name)
      File.open(file_name, "w") { |file| file << text.gsub("Framework", @appname) }
    end
    #next,change the rootpath away from namer#new
    file_name ='config/routes.rb'
    text = File.read(file_name)
    File.open(file_name, "w") { |file| file << text.gsub("namer#new", "pages#home") }
    flash[:notice] = "Enjoy your app."
    render('pages/home')
  end 

end

I also have a model called renamer. It's very basic. I removed the "< Base::ActiveRecord" because there's no database involved in this renaming process.

class Namer 
end

My problem is that when I enter a a new name into the form, rails returns an error that says:

TypeError in NamerController#create.  Can't convert Namer into String.

I am not sure why it is so eager to turn Namer into a string since I thought it was only using the @appname variable as a string. Any ideas on why this is failing?

UPDATE: So I've made some changes to the original code and here's how it looks now. For some reason the code did successfully run and do the name change on some of the files it's supposed to.

class NamerController < ApplicationController

  def index
    render('new') 
  end  

  def new
  end

  def create
    #first, change any instances of the term "framework" to the new name of the app   
    file_names = ['config/environments/test.rb', 'config/environments/production.rb', 
       'config/environment.rb']
    file_names.each do |file_name|
      text = File.read(file_name)
      File.open(file_name, "w") { |file| file << text.gsub("Framework", params[:appname]) }
    end
    #next,change the rootpath away from namer#new
    file_name ='config/routes.rb'
    text = File.read(file_name)
    File.open(file_name, "w") { |file| file << text.gsub("namer#new", "pages#home") }
    File.open(file_name, "w") { |file| file << text.gsub("post '/namer' => 
      'namer#create'", "") }
    flash[:notice] = "Enjoy your app."
    redirect_to(root_path)
  end 

end

For some reason when the code was semi-successful, it ended up deleting all of the congig/environments/test.rb file, which looks like this.

Framework::Application.configure do

  config.cache_classes = true
  config.serve_static_assets = true
  config.static_cache_control = "public, max-age=3600"
  config.whiny_nils = true
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false
  config.action_dispatch.show_exceptions = false
  config.action_controller.allow_forgery_protection    = false
  config.action_mailer.delivery_method = :test
  config.active_support.deprecation = :stderr
  config.assets.allow_debugging = true
end

I had accidentally moved around one of the lines in the routes folder, which somehow kept the renaming code from running. (No idea why). So I figure it may be related to the problem of having the test.rb file emptied of all text. Here is my routes.rb file.

Framework::Application.routes.draw do


  resources :users
  resources :sessions, :only => [:new, :create, :destroy]

  match '/signup',  :to => 'users#new'
  match '/signin',  :to => 'sessions#new'
  match '/signout', :to => 'sessions#destroy'

  match '/contact', :to => 'pages#contact'
  match '/about',   :to => 'pages#about' 
  match '/help',    :to => 'pages#help'


  post '/namer' => 'namer#create'    
  root :to => "namer#new"
  match ':controller(/:action(/:id(.:format)))'
end

SOLUTION: This is what my Create method ended up looking like. And now it works just like I wanted it to.

  def create
    #first, change any instances of the term "framework" to the new name of the app   
    file_names = ['config/environments/test.rb', 'config/environments/production.rb', 
       'config/environment.rb']
    file_names.each do |file_name|
      text = File.read(file_name)
      File.open(file_name, "w") {|file| file << text.gsub("Framework", params[:appname])}
    end
    #next,change the rootpath away from namer#new
    file_name ='config/routes.rb'
    text = File.read(file_name)
    File.open(file_name, "w") { |file| file << text.gsub("namer#new", "pages#home") }

    file_name ='config/routes.rb'
    text = File.read(file_name)    
    File.open(file_name, "w") { |file| file << text.gsub("post '/namer' => 
       'namer#create'", "") }
    flash[:notice] = "Enjoy your app."
    redirect_to(root_path)
  end 
Community
  • 1
  • 1
Ben Downey
  • 2,575
  • 4
  • 37
  • 57

1 Answers1

0

This line: text.gsub("Framework", @appname) is where the issue is. gsub is looking for a string/pattern as the second argument while you are passing it a whole object, @appname. Try @appname.to_s.

Update

Well you could just replace @appname in the gsub with param[:appname] and avoid the class entirely.

Or in Namer you could do:

class Namer
    attr_accessor :appname
end

and then do:

def create
    @appname = Namer.new 
    @appname.appname = params[:appname]  @appname.appname
    ...
    text.gsub("Framework", @appname.appname)
    ...
end
ScottJShea
  • 7,041
  • 11
  • 44
  • 67
  • Well, that definitely helped, but it hasn't solved my problem. On the brightside, the code was able to run without any errors. But instead of renaming the text according to what the user enters in the view, instead the app pops in this: Namer:0x007f9ab5b73e08. So the problem is that what's being typed in by the viewer is not being converted into the variable @appname like I was hoping it would. Any ideas? – Ben Downey Mar 13 '12 at 20:27
  • Well you could just replace `@appname` in the gsub with `param[:appname]` and avoid the class entirely. Or in Namer you could do `attr_accessor :appname` and then do: `@appname = Namer.new` `@appname.appname = params[:appname]` And then replace `@appname` with `@appname.appname`. – ScottJShea Mar 13 '12 at 20:33
  • I went with your first suffestion (avoiding the @appname variable all together). Very nice. I've tried it out a few times and for the most part, it works. But for some totally strange reason, when doing the rename in the "config/environments/test.rb" file, it erases everything instead of doing a find/replace. Everything else works great, but I can't figure out why it's eliminating all that text. – Ben Downey Mar 13 '12 at 21:02
  • That is weird. Would you mind editing your original post and putting what you have in `test.rb` there? Sanitized of course. – ScottJShea Mar 13 '12 at 21:06
  • The only way I get that behavior is an error occurs running the script. – ScottJShea Mar 13 '12 at 21:33
  • I was only able to get a blank `test.rb` when there was an error in the gsub... e.g. the file was opened but not written to; I had not declared `text` so `text.gsub` threw an error. Otherwise the code worked fine in my implementation. Does not mean much since I cannot replicate your env specifically. – ScottJShea Mar 13 '12 at 21:39
  • OK, so I realized that I had made a change to the routes folder and it turned out that what was keeping the renaming code from doing its job. (Not sure why.) Is there any way the routes.rb file could somehow still be interfering with the renaming? I've posted that up in the main section of my post. If you could take a peek, I'd appreciate it. You've been a lifesaver for me. – Ben Downey Mar 13 '12 at 21:52
  • If the other files in `file_names` work then it is probably not the routes. If you do `Rails.logger.debug("App name: #{params[:appname]}")` what shows up as the param being passed? You might also output `file_name` in `file_names.each` to see what the file name is being passed as. And I am glad to help. – ScottJShea Mar 13 '12 at 22:13
  • Ok. I so that and the name that app name seems to "get" the appname. `Started POST "/namer" for 127.0.0.1 at 2012-03-13 19:10:18 -0500 Processing by NamerController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"FUwjR1Et9YbxhBdpSDoKh2AoVCTpn6DZzc/skuFKMl0=", "appname"=>"Funk", "commit"=>"Name Your App"} Redirected to http://localhost:3000/ App name: Funk Completed 302 Found in 2ms` For a totally unknown reason, test.rb is now working fine. I've done the renaming three times and it's stayed each time. Only change was rebooting server. – Ben Downey Mar 14 '12 at 00:19
  • But I noticed that the end of there's one line not getting properly executed: ` File.open(file_name, "w") { |file| file << text.gsub("namer#new", "pages#home") }`. It's only that one. The code before and after is fine. What should I look for in the log file that would show how this code is being ignored? – Ben Downey Mar 14 '12 at 00:23
  • This is where blocks are a pain... I usually bracket the line with `Rails.logger.debug("Start")` and `Rails.logger.debug("End")` and then scan the space in between the Start and End to see what happened. There might be another way but I have not found it yet. – ScottJShea Mar 14 '12 at 01:34
  • I haven't figured out WHY it was a problem, but at least I figured out what the problem was. I had some gsub action where I was replacing two different patterns in the same file. I had to make those stand alone find/replaces, instead of jamming them into one. I posted my revised code above. Scott, thank you so much for your help. I couldn't have done it without you! – Ben Downey Mar 14 '12 at 13:12