Renaming controllers in Rails and cleaning out generated content - ruby-on-rails

I was following along with the railscast regarding the restful_authentication plugin.
He recommended running the command:
script/generate authenticated user session
Which I did, and everything generated "fine", but then sessions wouldn't work. Checking the site again, he mentions a naming standard and listed updated code which stated:
script/generate authenticated user sessions
With sessions being pluralized.
So now I have session_controller.rb with a SessionController in it, but I guess by naming standards, it is looking for SessionsController, causing the code to fail out with the error "NameError in SessionsController#create "
I see the problem, which is pretty obvious, but what I don't know is, how do I fix this without regenerating the content? Is there a way to reverse the generation process to clear out all changes made by the generation?
I tried just renaming the files to sessions_controller with e SessionsController class, but that failed.
While writing this, I solved my own problem. I had to rename session to sessions in the routes file as a map.resource and rename the view directory from session to sessions, and update session_path in the html.erb file to sessions_path.
So I solved my problem, but my answer regarding removing generated content still remains. Is it possible to ungenerate content?

Actually, script/destroy works for any generator - generators work by reading a script of sorts on what files to create; script/destroy just reads that script in reverse and removes all the files created, as long as you give it the same arguments you passed to script/generate.
To sum up: script/destroy authenticated user session would have removed all the generated files for you, after which you could have run script/generate user sessions without a problem.

I've never tried script/destroy, but if you're reverting changes that you just made, the generate command should give you a list of files added and changes made. If you're using a version control system of some sort, running status/diff might help as well.

You can just roll back to the previous revision in subversion, and start again, right? right? :-)
rails has script/destroy for 'ungenerating' stuff, but I suspect that will only work for the stuff rails ships with, not the restful authentication plugin.
I'd say your best bet is find-in-files (or grep -R if you're not using an IDE) - find everything that refers to your old SessionController and change it

Related

Rails 5 Upgrade: routes.rb file cleared out

I am upgrading a Rails app from 4.2.x to 5.0.x. After I updated all my Rails-related gems in Gemfile, I ran the rails task for updating all my files to conform to the newest version, as per the upgrade guide:
rails app:update
There were many conflicts in this command, so I pressed a to accept all conflicts and then review them manually before committing them. My main concern is what happened to the config/routes.rb file. Basically, the entire contents of the file, save for the Rails.application.routes.draw block and a single comment about the DSL added to the end of the file, were kept. All routes that have been added to the app over the years were cleared out, not to be found in any other file.
This issue doesn't block me, I'll simply checkout the file to bring it back to its former state. However, what especially concerns me is that an essential file was cleared out in what appears to be a normal situation for upgrading a Rails version. I'd like to see if anyone else has run into this issue, whether this is expected, what's going on. Comments from Rails maintainers are welcome. Thank you.
The app:update task is just a slightly modified version of the task that creates a new Rails application. It writes out files under config/ and bin/ based on the templates from the new Rails version. If you selected a to accept all conflicts, then that simply means that Rails is going to overwrite any differing files with its own copy without asking you. This is normal and expected. If you don't want that behavior, then don't press a.
config/routes.rb is almost certainly the one file under config/ that will differ almost completely from the empty boilerplate file.
Realistically, Rails can't be expected to parse your custom changes and merge them with a new template.
For what it's worth, I like to start out doing exactly what you did, with a clean working directory just let the app:update task overwrite anything it wants to, and then go through all the changes with a side-by-side, SCM-aware diff tool like vim-fugitive to stage or discard the differences.
Well, just don't accept all conflicts, take a look in each one of it. Making version upgrades of 1 level of magnitude may change a lot of things and the process takes a while.
First take a look on the changes in the framework and do the process carefully. You may be breaking a lot more stuff that you are not noticing:
http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-4-2-to-rails-5-0

How do you convert a Rails 5 API app to a rails app that can act as both API and app?

I initially created it in rails 5 with the --api tag.
From http://edgeguides.rubyonrails.org/api_app.html,
I removed config.api_only = true
I changed
class ApplicationController < ActionController::API
end
to
class ApplicationController < ActionController::Base
end
The problem I'm having now is when the view is getting rendered, ex. welcome/index.html.erb, the corresponding CSS file assets/stylesheets/welcome.css.scss is not.
Any idea how I can fix this, or more generally convert the API application to a full app?
Thanks!
I ran into this same problem and I believe I've solved it. I was hoping to find a simple rails generator to convert it, but unless I've missed something it's not that easy. However, rails does make it easier than doing it totally manually.
The key is that the rails new command can be used on an existing app. Note that this answer assumes you know how to use git and are using it on the existing app.
First and most importantly, make a new branch. This serves two functions, 1) so you shouldn't lose your work if you mess it up (although it still might be a good time to back it up, like to GitHub), and 2) so you can compare the files that have conflicts after this process and retrieve any work that this process overwrites (it wasn't much for me, but it was important).
In the terminal, from the directory of the app you want to change from API only to standard. Run the following commands to go up one directory and then have rails write a new project over your existing one. Use the same options on the second command that you used when creating your app initially. For example, for me I replaced [options] below with -d postgresql --skip-turbolinks --skip-spring -T because those are the options I used when creating my app. I'm using the --skip-bundle flag because it might change your Gemfile more than you want it too and you'll probably want to change some of it back before bundling.
$ cd ..
$ rails new your_app_name --skip-bundle [options]
Now rails is going to go through it's usual process of creating all the files for a new app, but this time it's going to skip almost all of them because they're already there. It will stop on each one on which there is a conflict, and that's where you'll need to analyze the conflicts one-by-one.
Here's what worked for me on the conflicted files:
Submit d on each one of them to see the differences.
If the difference is only adding lines, then allow it with Y. That's why we're doing this after all.
If the difference is only removing code, then reject it with n.
If the difference is both adding and removing code, write down that file to come back to after this process. Then accept it with Y.
After this is finished, use git to examine the difference on each file from (4) that you wrote down. You'll want to keep the changes that rails added, but then you'll likely want to copy all the code that it removed back in. This will probably include the Gemfile.
One notable difference is that rails changes the application controller from inheriting from ActionController::API to ActionController::Base. I want one controller for each, so I created a new file `app/controllers/api_controller.rb'. Then I copied what was in my original ApplicationController over to the new file and just changed the class name to ApiController. Then I changed all my existing API controllers to inherit from the new ApiController instead of from ApplicationController.
After that is done, then run bundle install to install the gems rails added into the app.
That worked for me. I hope it helps. Good luck!
From a directory outside of the api application (such as its parent - cd ..) I would do
rails new comparison_real_app
and then compare the contents of the comparison_real_app with your app and copy over the files that are missing into the api app and change any other files as required.
So there's probably more things that will need to be done as I (you) go along, but to resolve the issue with stylesheets you need to manually create your views/layouts/application.html.erb and assets/stylesheets/application.css files.

How to generate a dummy app inside an already existing rails engine

I came to work for a company recently that has been working on a specific rails project for a while. Dropped in the middle of the development process, I'm beginning to go back and write tests for the existing code as well as the code currently being produced.
Testing the rails 4 app was easy enough, but once I got to testing the engine, I hit a mental block. After doing my due diligence, I found that most people take an approach like this (http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl), but the common thread I saw in all of these responses was that people were building these apps from scratch, and thus had a dummy app generated for them automatically. I don't have the benefit of being able to generate everything from scratch, and have to work with what I was given, so what
I'd like to know is if there's a way to retroactively generate just the dummy application. Is there something simple I can type into the console and have it generated for me? Or is there a longer, slightly less pretty route? Or would a different strategy be better altogether?
Given that the dummy app is not supposed to be tied to the parent gem except for some vague names, that may do it:
cd some_path_where_your_engine_IS_NOT
rails plugin new YOUR_ENGINE_NAME --mountable --dummy-path=spec/dummy --skip-test-unit
mv YOUR_ENGINE_NAME/spec/dummy /real/path/to/YOUR_ENGINE_NAME/spec
rm -rf YOUR_ENGINE_NAME # cleanup useless cruft
Also, you may be interested in this answer to generate the app with the exact same rails version.
If the engine is within a parent app delete the engine from your Gemfile
Rerun the rails plugin new .. command you used to create the rails engine, but with the --skip parameter. This will create all the files, including dummy that do not exist in your engine, but leave existing files alone.

How to use acts-as-commentable-with-threading in Rails

I am developing my first rails site (yup, i am a rails idiot).
I'm writing a blog, and i got to the comments part.
I installed acts-as-commentable-with-threading ( GitHub ), i made and ran the migration like the install instructions said.
I have added acts_as_commentable to my Posts model and i have a Comments controller
When i add
#comment = Comment.build_from(params[:id],1, params[:body] )
I get the error.
undefined method `build_from' for #
Clearly i am doing something terribly wrong, and i don't really get the example. What should i be feeding to build_from? Can somebody explain this plugin step by step? :)
Or is there an easier way to get simple threaded comments?
Did you by chance define your own comment model? If so that is going to completely override the model from the plugin that defines build_from in the first place. I ended up getting around this by creating a module with the extra stuff I wanted then creating an initializer to include it, which works perfectly.
As an aside, the first parameter to build_from needs to be the actual commentable object the comment is to be connected to, not just an id.
I'm currently using this plugin in production and can assure you it works :)
Besides the reason of not restarting server (btw you shouldn't use nginx + passenger for development, simple mongrel or thin will do the job better in this case) I can think of two more:
You didn't install plugin (or something wrong happened during installing). However this is unlikely as you could run migration ok right?
You have comment model in app/models and rails doesn't load it from plugin. In this case you might want to try requiring file with plain old require.

Rails: Where to place plugin files

I am relatively new to Rails and recently found a couple of useful gems like authlogic that will help in getting the project up and about really fast. However, I have been wondering where to place the model, view, and controller files that are dependent on the plugin, but are core concepts of my project.
For example, is it better to place the User, Role, Session, etc.. models and related controllers with the plugin inside the vendor/ directory, or should I place them inside the root model/, view/, and controllers/ directories respectively?
Even models/views/controllers dependent on plugins should be kept in the app/model, app/view, and app/controllers directories along with your other code.
The "structural" reason is that the bulk of all those files will still be specific to your application. You will probably end up adding fields to the user, or adding has_many statements to your User model, etc. You want all that code with the rest of your core application code in the app directory.
The "functional" reason is that vender/plugins is only for the code specifically relating to that plugin and is treated differently during development. For instance, when you add a new plugin, it is not auto-loaded in development mode. So if your core files were there, they would not be auto reloaded even in development mode.
Anything you write should be in the standard directories. Use vendor for vendor-provided code.
Just as a heads up it is very hard to go wrong watching railscasts on topics you are new to.
Ryan Bates has two covering authlogic and authlogic with OpenID and in anticipation of your next step after authentication- authorization: He has some covering access control as well: Declarative Authorization, and CanCan.

Resources