How to test devise models, controllers and views using RSpec? - ruby-on-rails

I am used to generating my rspec controllers & models using rspec_X syntax, e.g.
script/generate rspec_model Person
script/generate rspec_controller Person
However if I want to use devise to create a Person model the syntax is:
script/generate devise Person
which works OK, but does not create any of the rspec test files / dirs.
Is there are command I can use to generate both?
(Ruby 1.8, Rails 2.3)
Thanks!

These models and controllers are tested internally to Devise and so you shouldn't be duplicating the effort yourself. If you'd like to test that users can sign in, sign out, register and retrieve their password, I would recommend you use Cucumber to write tests to test Devise's integration with your application.

I am used to generating my rspec controllers & models using rspec_X syntax
You can still use that if you want to create the rspec structures but you'll likely want to decline overwriting your model. For example, here's my rspec_model output:
$ script/generate rspec_model Person
exists app/models/
create spec/models/
create spec/fixtures/
overwrite app/models/person.rb? (enter "h" for help) [Ynaqdh] n
skip app/models/person.rb
create spec/models/person_spec.rb
create spec/fixtures/people.yml
exists db/migrate
create db/migrate/20100826043436_create_people.rb
I just told it not to overwrite app/models/person.rb.

Related

Listing the different scaffolds generated in your rails application

I have generated two scaffold using the following two commands:
$:- rails generate scaffold User user:string gender:string
$:- rails generate scaffold Microposts microposts:string
Is there any command that will list me the different scaffolds i have generated so far?
It should give me the output similar to this:
Scaffold generated:
User
Microposts
Not that I know of, but you can see the direct result in your application, plus after each scaffold you see which files are generated. To quote RoR guides:
A scaffold in Rails is a full set of model, database migration for that model, controller to manipulate it, views to view and manipulate the data, and a test suite for each of the above.
A scaffold in itself is not one thing, it's a collection. What would be the point of only displaying the name you used to scaffold all these files?
I don't think so - scaffolding generates models, views and controllers for a given class (in your case User and Microposts) - if you look at app/models you'll see User.rb and Microposts.rb. So maybe that's nearly the same thing?

Having default Rails generators call a custom generator

To be clear, here's NOT what I'm trying to:
Have my custom generator call a default Rails generator
Replace a default Rails generator with my own
What I want to do is have my generator be invoked automatically when I call:
rails generate scaffold User name age:integer
I'm not writing a test replacement or anything, it's completely custom. All information I find about generators out there involve one of those first two cases but not what I want to do. As soon as I found hook_for I immediately thought that was exactly what I needed, but it appears to do the opposite -- invokes another Rails generator from inside of my custom one (if I wanted a test file created for my custom generator I'd call hook_for :test_framework and then define a TestUnit::MyCustomGenerator class somewhere).
I suppose I could monkey patch the default scaffold generator to call mine but that feels dirty. I've looked into some gems that do something similar like https://github.com/Skalar/i18n-yaml-generator but trying to convert that to use an initializer and lib/generators isn't working for me. The scaffold_generator runs but mine never gets called.
for me it works from lib/generators/
$ rails g generator scaffold
create lib/generators/scaffold
create lib/generators/scaffold/scaffold_generator.rb
create lib/generators/scaffold/USAGE
create lib/generators/scaffold/templates
$ rails g scaffold
Usage:
rails generate scaffold NAME [options]
....
what/will/it/create
http://guides.rubyonrails.org/generators.html#generators-lookup
another way may be :)
fork railties gem
override Rails::Generators::ScaffoldGenerator class to your liking
install locally or specify source path in Gemfile
also if 'its completely custom', it is just fair to call it a different name, no?

Create Ruby on Rails views (only) after controllers and models are already created

I've obtained a project that have controllers (minimal code only) and models, but the views are missing. Is there a way to generate the views only using scaffold or another tool?
rails g scaffold User --migration=false --skip
The --skip means to skip files that already exist. (The opposite is --force.)
If you don't want helpers, --helpers=false.
Sample output after deleting my User views:
invoke active_record
identical app/models/user.rb
invoke test_unit
identical test/unit/user_test.rb
skip test/fixtures/users.yml
route resources :users
invoke scaffold_controller
identical app/controllers/users_controller.rb
invoke erb
exist app/views/users
create app/views/users/index.html.erb
create app/views/users/edit.html.erb
create app/views/users/show.html.erb
create app/views/users/new.html.erb
create app/views/users/_form.html.erb
invoke test_unit
identical test/functional/users_controller_test.rb
invoke helper
identical app/helpers/users_helper.rb
invoke test_unit
identical test/unit/helpers/users_helper_test.rb
invoke assets
invoke coffee
identical app/assets/javascripts/users.js.coffee
invoke scss
identical app/assets/stylesheets/users.css.scss
invoke scss
identical app/assets/stylesheets/scaffolds.css.scss
This is what the scaffold generator calls internally:
rails g erb:scaffold User
erb is the templating engine used, so you can also use haml:scaffold.
You must explicitly specify the fields you would like the scaffolding to use--rails does not automatically deduce them from the created model. For example:
rails g erb:scaffold User firstname lastname reputation
See rails g --help for options like skipping, forcing overwriting, and dry runs or generate scaffold --help for information specific to generating scaffolding.
I just encounter the same your problem. I did it. More detail is below:
- First I rename views/your_model folder to views/your_model_bak. In order to revert if fail later
- Then, execute command
rails g scaffold YourModel [field[:type][:index]] --skip
Don't forget --skip option, it will not create exist files (controller and model in this case and few other files)
Make sure list [field[:type][:index]] is up to date
-- Finally, you should update your permit in your_model controller.
Hope it can help you.
"Another tool"...
How about being able to do "script/generate view_for model_name"? :)
There is a gem for that - View Mapper. It has Ruby on Rails 2 and 3 versions.
One small tip is to add "--no-test-framework" if using Rspec and don't want test files generated for each view in spec/views
To generate views after controller and models are already created, you may use the command line. You switch to the folder in which you want to create the new view. For example:
$ cd name_app/app/views/controller_name
$ touch name_file
To go back of one directory use:
$ cd ..

How does these rails generate command differ? and what basically rails generate means?

rails generate migration
rails generate model
rails generate scaffold
rails generate controller etc.
How these differ?
According to rails guides:
Using generators will save you a large amount of time by writing boilerplate code, code that is necessary for the app to work, but not necessary for you to spend time writing. That’s what we have computers for.
rails generate commands family used to provide simple and easy way for developer to create different object types.
rails generate migration - creates DB migration script in db/migrations directory so developer can setup his DB.
rails generate model - creates model class with associated migration, test and fixtures (test data).
rails generate scaffold - creates all nedded classes with basic logic and presentaion. It creates controller (with simple CRUD logic), model, fixtures, functional and unit tests.
rails generate controller - creates controller with associated functional tests, helper and basic views templates.
You can read more here: http://guides.rubyonrails.org/command_line.html#rails-generate
They differ in the sense that they generate different stuff.
migration will generate a database migration file,
model will generate a model(with a migration and a spec by default)
scaffold will generate a scaffold of a resource
and controller will generate a controller.
generate means it will create the files for you with boiler plate code already in place(you will still need to edit them though..but scaffold can get you working with a basic application already)
Read more about it here: http://guides.rubyonrails.org/command_line.html#rails-generate
rails generate is a command line script for quickly generating the code for various Rails' constructs.
In the example you give they differ by what they produce, with the first argument being the type of code generated. For example if I wanted to create a User model I would run:
`rails generate model user`
The model file, test file and migration would be created for me.
You should read the Rails' documentation to find more.
**rails generate model user:
The above command create a Template Object that is a mirror image of the database table.
For example, if you have a database table that is named users that has a name:string, and email:string field,then "rails generate model user" create an Object that mirrors that user table with a few addition.
Here are the similarity they both have name:string,email:string the both have the word user.
The difference are few but significant: user is Capitalized in the model name like "User".
The Table add create_by and updated_by automatically.
migration:db create the database mirror using the model as a model.RECURSION ANYONE?

Rails: How to run `rails generate scaffold` when the model already exists?

I'm new to Rails so my current project is in a weird state.
One of the first things I generated was a "Movie" model. I then started defining it in more detail, added a few methods, etc.
I now realize I should have generated it with rails generate scaffold to hook up things like the routing, views, controller, etc.
I tried to generate the scaffolding but I got an error saying a migration file with the same name already exists.
What's the best way for me to create scaffolding for my "Movie" now? (using rails 3)
TL;DR: rails g scaffold_controller <name>
Even though you already have a model, you can still generate the necessary controller and migration files by using the rails generate option. If you run rails generate -h you can see all of the options available to you.
Rails:
controller
generator
helper
integration_test
mailer
migration
model
observer
performance_test
plugin
resource
scaffold
scaffold_controller
session_migration
stylesheets
If you'd like to generate a controller scaffold for your model, see scaffold_controller. Just for clarity, here's the description on that:
Stubs out a scaffolded controller and its views. Pass the model name,
either CamelCased or under_scored, and a list of views as arguments.
The controller name is retrieved as a pluralized version of the model
name.
To create a controller within a module, specify the model name as a
path like 'parent_module/controller_name'.
This generates a controller class in app/controllers and invokes helper,
template engine and test framework generators.
To create your resource, you'd use the resource generator, and to create a migration, you can also see the migration generator (see, there's a pattern to all of this madness). These provide options to create the missing files to build a resource. Alternatively you can just run rails generate scaffold with the --skip option to skip any files which exist :)
I recommend spending some time looking at the options inside of the generators. They're something I don't feel are documented extremely well in books and such, but they're very handy.
Great answer by Lee Jarvis, this is just the command e.g; we already have an existing model called User:
rails g scaffold_controller User
For the ones starting a rails app with existing database there is a cool gem called schema_to_scaffold to generate a scaffold script.
it outputs:
rails g scaffold users fname:string lname:string bdate:date email:string encrypted_password:string
from your schema.rb our your renamed schema.rb. Check it
In Rails 5, you can still run
$rails generate scaffold movie --skip
to create all the missing scaffold files or
rails generate scaffold_controller Movie
to create the controller and view only.
For a better explanation check out rails scaffold
This command should do the trick:
$ rails g scaffold movie --skip
You can make use of scaffold_controller and remember to pass the attributes of the model, or scaffold will be generated without the attributes.
rails g scaffold_controller User name email
# or
rails g scaffold_controller User name:string email:string
This command will generate following files:
create app/controllers/users_controller.rb
invoke haml
create app/views/users
create app/views/users/index.html.haml
create app/views/users/edit.html.haml
create app/views/users/show.html.haml
create app/views/users/new.html.haml
create app/views/users/_form.html.haml
invoke test_unit
create test/controllers/users_controller_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
I had this challenge when working on a Rails 6 API application in Ubuntu 20.04.
I had already existing models, and I needed to generate corresponding controllers for the models and also add their allowed attributes in the controller params.
Here's how I did it:
I used the rails generate scaffold_controller to get it done.
I simply ran the following commands:
rails generate scaffold_controller School name:string logo:json motto:text address:text
rails generate scaffold_controller Program name:string logo:json school:references
This generated the corresponding controllers for the models and also added their allowed attributes in the controller params, including the foreign key attributes.
create app/controllers/schools_controller.rb
invoke test_unit
create test/controllers/schools_controller_test.rb
create app/controllers/programs_controller.rb
invoke test_unit
create test/controllers/programs_controller_test.rb
That's all.
I hope this helps

Resources