Posted in Updating Nested Form / Model Attributes
I have a nested form on a Devise signup page. The user signs up and then they also fill out their company info (Name , Address etc.). My User and Company model are associated through a Role model which has id_user and id_company. My form has nested form_for tags for the Role and Company models. The sign-up works like magic and the Role is created automatically with the id_user and id _company filled in.
Now the part I can't figure out. When they sign up the Company is new and the User is the first and therefore should be the 'owner' Role. I have some other attributes I want to set ( :role => 'owner', :active => 1, :default_role => 1 etc.). The role attribute will be used later for an authorization system - probably with Pundit.
I want to do this on the backend with the controller. The intermediate Role is created via 'magic' but can you hook into that process and further update the record? I know I could probably add a hidden field in the form but to me that is opening a security hole. Here is my StackExchange post that has the code etc.:
Ok.. here is a StackExchange post on this:
It has my Models etc.
I forgot to mention - I tried your method and the user gets created but the company is not getting created and there is no errors or even any active record activity in the logs when it happens. I suspect I have my associations messed up because there is no direct link between User and Comapny with Role in the middle.
Yes - that's essentially what I am doing.
My system has some differences. First off the user could exist already. As long as the company is unique they can continue.
Second I have a Role model that associates the User to the company. I need to create / identify the user, create the company and a role all at the same time and like I mentioned roll it all back if any validation fails.
This is where I struggled with even letting people sign up directly. At first I thought I would set up a company manually and add the first owner user. This way I can watch for duplicate companies etc outside of a normal validation etc.
However with a direct sign up people can get into a trial account an start test driving the site right away.
I was tying to implement this and had a revelation - I need to register the Company and then using nested forms to create the user and role. Once the user registers the company the user is automatically created (unless they exist) and then the role is created to glue the two together.
Now - I have already created my default Devise install on the User model. I still want to use Devise for authentication but can I still use it for registration or I am overriding manually? Once a company is created all new users created under that company will be by another existing user. You will not be able to signup unless you are creating a new company.
I think in this case I can handle the validations in my controllers. It's a bit ugly with all the :through associations.
I am going to go with the email only. It's just easy - I personally hate having to pick a username. My email is the easiest thing to remember.
Here is a great link I came across on the very subject:
It even gets into login vs signing and signup vs register.
Thanks for the tip on the nested model validation :)
Posted in Styling with Bootstrap Sass Discussion
I started a new app today and it seems that the docs have changed:
You need to remove the require directives from your css files but when you do that it seems that all the other CSS files do not get included. You need to manually import each one in your new application.scss file. I seem to be missing something here (and I did save my files this time ;^)
Related to my previous thread (https://gorails.com/forum/structure-guidance-multi-tenancy-authentication-authorization) I plan to have authorization with Devise and some sort of role based system (perhaps Pundit) tied to a Company model.
When the user signs up they are creating the new Company record and a user / role at the same time. I can see a few issues and I am not sure how to handle them:
1.) Email adress vs username
Some quick Googling indicates that email addresses as username might be a bit more prone to security issues but personally it's nice to use them as it's easy to remember and saves one less field from the scheme. Any thoughts?
2.) Duplicate Companies
With my target market I don't this being a big issue. I am going to require the company name - ABC Widgets Inc. for example. It is possible for two people to sign up "ABC Widgets Inc." and "ABC Widgets" etc. I could do a validation search to look for similar companies but that opens up privacy issues. I was also thinking that I could add a search on existing user email domains too. If email@example.com tries to register "ABC Widgets Inc." and then firstname.lastname@example.org tried to register "ABC Widgets" that would be a chance to stop them and email Sally about Tom's interest.
My first thought is to just leave it along an monitor new signups etc and contact the users when issues arise. I may me making this a bigger issue.
3.) Updating two models at the same time
The user fills out the sign-up form and then my controller chugs away planning to add a Company, User and Role record. I need all three to execute successfully otherwise roll back - can you do that in Rails? The Role is easy - it's a new company and in my system the user could actually already exist.
It took me forever to build but I did it from scratch a few years back on a project that I still have yet to finish. I works slick but I am sure it could be done better than the way I did it. I used the ancestry gem and a few Railscasts episodes to cobble it together.
I forgot we had this thread going? I was using EV's on my server but after the last reboot they got wiped? How do I keep these persistent or do the symlink like you mention above?
Chris - can you elaborate on this or point me to a tutorial on setting this up? I had done this with ENV variables but after my last VPS reboot they all seemed to be lost and I can't recall how I set them before.
Here is a Pro episode suggestion - take this and add nested comments and some AJAX to it :)
Yup - way ahead of you. It was:
# passenger_ruby /home/deploy/.rbenv/shims/ruby; # If you use rbenv
that I forgot to change. Now that I fixed that I am hitting:
Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`
This looks like a Rails 4.1 feature that I had not seen before. I copied and pasted the test key for now and created a dummy index.html file in the public folder and I am up and running finally! Next is to figure out how to set the determine and set key base (and others such as passwords etc.) env variable on the remote server. Thanks for your help.
Thanks Chris - that did the trick. Now I have an entire new issue that is beyond this thread. Passenger won't start:
cannot load such file -- bundler/setup (LoadError) /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require' /usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require' /usr/lib/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:263:in `block in run_load_path_setup_code' /usr/lib/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:366:in `running_bundler' /usr/lib/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:261:in `run_load_path_setup_code' /usr/share/passenger/helper-scripts/rack-preloader.rb:100:in `preload_app' /usr/share/passenger/helper-scripts/rack-preloader.rb:158:in `<module:App>' /usr/share/passenger/helper-scripts/rack-preloader.rb:29:in `<module:PhusionPassenger>' /usr/share/passenger/helper-scripts/rack-preloader.rb:28:in `<main>'
I turned on the user friendly errors. I will do some Googling but have a suspicion that my ruby versions are different. I have 2.1.3 on my server but the error page shows 1.9.3.
deploy@oilfieldlocator:~/oilfieldlocator/releases/20141210203639$ RAILS_ENV=production bundle exec rake db:create PG::InsufficientPrivilege: ERROR: permission denied to create database : CREATE DATABASE "locator_production" ENCODING = 'unicode'
Now I know enough to add create privileges to my user but going forward what would be the 'least privileges' that this user should have from a security standpoint?
deploy@oilfieldlocator:~/oilfieldlocator/shared$ RAILS_ENV=production bundle exec rake db:create Could not locate Gemfile
Do I run this from the latest releases directory?
Ok - some headway. I forgot to update the database.yml file on the server and I had some username / password issues. Now I seem to have a chicken and the egg issue. I get the process on the tutorial where after your first deploy you run rake to initialize the database on the server but my deploy seems to be trying to connect before the repository is even uploaded:
INFO[a0fcf2e4] Running ~/.rbenv/bin/rbenv exec bundle exec rake db:migrate on 18.104.22.168 DEBUG[a0fcf2e4] Command: cd /home/deploy/oilfieldlocator/releases/20141210203639 && ( RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.3 RAILS_ENV=production ~/.rbenv/bin/rbenv exec bundle exec rake db:migrate ) DEBUG[a0fcf2e4] rake aborted! DEBUG[a0fcf2e4] ActiveRecord::NoDatabaseError: FATAL: database "locator_production" does not exist DEBUG[a0fcf2e4] Run `$ bin/rake db:create db:migrate` to create your database
I would run rake but nothing has been uploaded to the 'current' directory to run it from.
Changed that to host: 127.0.0.1, ran:
git add. git commit -m "update" git push cap production deploy
I don't think capistrano is getting the most recent git repository because I still get the same errors with the external IP reference:
INFO[b739d356] Running ~/.rbenv/bin/rbenv exec bundle exec rake assets:precompile on 22.214.171.124 DEBUG[b739d356] Command: cd /home/deploy/oilfieldlocator/releases/20141210201232 && ( RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.3 RAILS_ENV=production ~/.rbenv/bin/rbenv exec bundle exec rake assets:precompile ) DEBUG[b739d356] rake aborted! DEBUG[b739d356] ActiveRecord::AdapterNotSpecified: '126.96.36.199' database is not configured. Available: ["default", "development", "test", "production"]
default: &default adapter: postgresql encoding: unicode # For details on connection pooling, see rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling pool: 5 development: <<: *default database: locator_development test: <<: *default database: locator_test production: <<: *default url: 188.8.131.52 database: locator_production username: oilfieldlocator #password: <%= ENV['LOCATOR_DATABASE_PASSWORD'] %> password: *************
I have been too lazy to get around to setting the ENV variables
Ok - I think I sort of sorted this out. I had not committed / pushed my site to git.
I did that and now I am having endless issues just trying to get the empty default rails app to deploy.
I can't seem to get the deploy to work at all. Here is where I am stuck:
INFO[9a80e4f2] Running ~/.rbenv/bin/rbenv exec bundle exec rake assets:precompile on 184.108.40.206 DEBUG[9a80e4f2] Command: cd /home/deploy/oilfieldlocator/releases/20141210083340 && ( RBENV_ROOT=~/.rbenv RBENV_VERSION=2.1.3 RAILS_ENV=production ~/.rbenv/bin/rbenv exec bundle exec rake assets:precompile ) DEBUG[9a80e4f2] rake aborted! DEBUG[9a80e4f2] ActiveRecord::AdapterNotSpecified: '220.127.116.11' database is not configured. Available: ["default", "development", "test", "production"]
I am getting ready to give up on this. That IP is the one for my VPS but I changed that to localhost in my database.yml file. Why do I still see it on the deploy errors??