Creating demo data for rails application on per account basis - ruby-on-rails

I would like to create some sample data for a user when they register so that they do not have to start with a blank canvas.
I am presently defining lots of static data in classes which I then iterate over, however setting up relationships is cumbersome and I think that this is quite brittle.
I think that having some demo fixtures (separate from my test set) would be a good way to do this, but as records are tied to an account I can't see how I can insert this data and attach it to the account when loading the fixtures.
This might not even be the best approach, but if there is a better way then please let me know.

Every RAILS application has seeds.rb present in db/ folder.So as the name says,it is used to seed your db by default records that you may want.
So this is how i am using my seeds.rb.Creating many records,constants and then to put those records in your db,just run rake db:seed assuming you have db ready.See HERE for more infor
my seeds.rb
###seed eventype table with default values
["birthday","farewell","party"].each do |f|
EventType.find_or_create_by({name:f.upcase})
end
###create users with random names
##after creating users,create associated fields
%w[mike john paul allen harry betty].each_with_index do |name,index|
#user = User.find_or_create_by({email:"user_#{name}#gmail.com"})
##user has_one address
#user.create_address({:address_2=>"street 1,near berry lane"})
##user has_many pictures
#user.pictures.create!({:title=>"Title of the picture",:picture => File.new("#{Rails.root}/public/images/test.jpg")})
end
You can even use (0..6).each do loop to create n records as you wish in db.
for example:-
(0..100).each do
###create user/pictures etc
end
However you must be careful to follow all validations and create valid record else this wont work.
for example,if in user model,you are expecting username as well,then in seeds.rb,you must pass the username so that it passes the validation easily.
=========================================================================
IF you dont want to use db seed,you can use a callbacks on: :create(i dont prefer observers).Simple example can be :
##in user.rb
after_commit :create_default_account, on: :create
def create_default_account
##assuming user has_one :account
self.build_account({:name=>"Default account"})
end
HOPE IT HELPS

Related

Rails Cookies to manipulate database entries

I am trying to create a Rails app and I have a database consisting of author and a quotation by that author.
Now different users can choose to destroy or kill quotations from the database however it must only be deleted for that particular user i.e other users should still be able to see quotes that they didn't delete even if another user did.
I know that I would need to implement cookies but other than that I am unsure how to proceed. Can anyone point me to a tutorial or give me some pointers to get started on this complex task?
You surely have a User model in your application - one 'Rails-like' way to go about this would be to add a has_and_belongs_to_many relationship between User and Quotation.
This creates a relationship between each individual user and 'their' quotations. This relationship can be deleted without actually deleting a quotation, so all quotations would still be available to other users. If you want each user to be able to see all quotations by default, you would need to set up the relationship in advance.
Assuming you are using Devise to log your users in, all you'd need to do then is to replace Quotation.all with current_user.quotations in whichever controller you are using to display quotations.
The Rails guide linked above is quite helpful but basically you just need to add something like the following:
class User
has_and_belongs_to_many :quotations
before_create :add_quotations
def add_quotations
self.quotations << Quotation.all
end
#etc...
end
class Quotation
has_and_belongs_to_many :users
#etc...
end
and then run a migration adding a new table called users_quotations with the columns user_id and quotation_id.
EDIT
As #Yule pointed out this wouldn't let users see any quotations that were created after they were, and it would be quite annoying to have to set up the join tables in advance, so a more efficient way would be to have an excluded_quotations join table instead. So users can see all quotations except the ones that they have excluded.

Add 'current_user' to a model. (Devise) Rails

Hi I'm new here and also new in rails.
I want to add a couple values by default to a database called books (Model: Book.erb)
there is a user who creates these books(current_user), and I thought that a way to identify who creates and deletes this content is by adding some default values from the user and clasificate them (to be specific username and password)
my table ":books" has available two fields for adding username and password
I tried to do this:
# Book.erb
class Book < ActiveRecord::Base
after_save :set_default_values
def set_default_values
self.username = current_user.username
self.password = current_user.encrypted_password
end
end
but it seems to be that I can't call 'current_user' from this model.
I was reading a pratice on this blog
but some were saying that this method violates the MVC pattern, do you agree with them?
do you guys know a better way to do this process without violating the pattern?
Well, I'm not sure I can conceive of why you'd want to store a user name and user password in a book table as even if it was easily explained, it would be in violation of normalization practices for good database design which pretty much states you should only express a field once and then share it where it needs to be shared.
Now, assuming you must do this for some reason I can't conceive, I'd have to ask if "username" is your actual field or is it just "name" which is more standard Rails. And, I believe you'll have to have a relationship between these models to pull the data from one into the other and I don't see that book has_many users or one or belongs_to or anything of that sort.
With a relationship between book and user you have access to all user properties without writing them anywhere other than the user table. So I think you probably want to look at that.

How create separate DataBase for each user

I am using Rails 3 and want whenever user will be created, then separate Data Base should be created for newly created user.
e.g if I have 13 migration in my application, so 13 tables should be created for newly created user.
How I can achieve this functionality?
Also check out the audio/video that goes along with James slides here http://www.confreaks.com/videos/889-railsconf2012-ten-things-you-didn-t-know-rails-could-do. Move forward to around 15:30 for the section on one user per database.
This is a really bad idea to handle many DB in Rails!
You can add a field, say, user_id in each of your tables that are needed to be separated and then apply default_scope to their respective models (or make an abstract model with default_scope via self.abstract_class = true and inherit your "shareable" models from it).
Your default_scope, as you might guess, should look like:
default_scope lambda { where(user_id: current_user_id) }
How to get the current user, you may ask?
Models can't access session, so you can make the following "hack" in order your scope to work:
#in ApplicationController
before_filter do
user_id = session[:user_id]
ActiveRecord::Base.class.send :define_method, :current_user_id, lambda { user_id }
end
I guess you got the idea.
This is best post i follow and solve my problem
http://7fff.com/2010/12/02/activerecord-dropcreate-database-run-migrations-outside-of-rails/

Ruby on Rails: How should I seed my database with account specific data?

I am creating a SAAS app using Rails 3. When a user creates a new account, the database needs to populate with a lot of data. Some of the data will be specific to the newly created account. I don't necessarily want to do this all with Models within the controller "sign up" action. What would be the best way to do this?
From the sounds of things you should be using a callback within your User model. Most likely: a before_create or after_create (depending on your exact needs). You can then have the user model handle the creation of the account specific data, rather than your controller and thus adhere to the ideals of 'fat-model, skinny-controller'.
class User < ActiveRecord::Base
after_create :setup_account_data
private
def setup_account_data
# create other data as required
end
end
Pretty simple really, after the user model is created - the setup_account_data method will be called. A list of the other available callbacks is here.
A couple of approaches come to mind.
simple ruby. This is similar to what is done when you run rake db:seed -- execution of a ruby script.
fixtures. If you dump a database to fixtures [http://snippets.dzone.com/posts/show/4468], you can modify the fixtures so that the data that needs to be customized is done in erb blocks. This is the same technique that is used often in test fixtures.

Populating a database after "Sign Up"

I would like to populate various tables in my database after a new customer signs up to use our web application. I'm wondering what the best way to do this is, the main requirement being that it should not require any intervention by me. Most of the data is static (but can be changed by the customer later (like preferences for example)), but will obviously need the customer's ID as a way of linking the created records to this customer.
I considered putting a few
Object.create(:customer_id => #customer.id, :yummy => "maybe", :etc => true)
statements in the controller that handles signups, but that annoying little alarm bell that tells me there's a better way is going off again!
Thanks in advance for any suggestions!
Gav
The problem with khelll's solution is that if you create a new Account using from outside of the register action (for example, in an admin module), it's database won't be populated.
So I'd prefer something like the following :
class Account < ActiveModel::Base
def after_create
populate
end
private
def populate
# Your logic
end
end
The after_create callback will be called after any account creation.
That's more MVC and DRY compliant ;)
In your controller
class AccountController < ApplicationController
after_filter :populate_db :only=>[:register]
def populate_db
# whatever stuff
Account.populate
end
end
And put the logic inside your model:
class Account < ActiveModel::Base
def populate
# your logic
end
end
two ways
a trigger function in your database that does this
a callback in your user model on creation
Can you not just set defaults in your database?
I'm using a YAML file to populate more than ten tables in database during signup. This approach has some positive side-effects for me:
I can easily change the contents of the seed data for new account
It is very easy to add localized versions of initial content, i can let YAML files translated easily through 99translations.com
I'm planning to add data import feature later on where new clients can import their data during or right after signup so they can just take the import file template and customize it for their own needs.
There have been some downsides too:
Inevitably, when data schema changes, sometimes i have to modify all localized versions of these files.
It is one piece of ugly code i have that maps the foreign keys between all the new records. Maybe i can use some schema descriptors here...
As i get around 300 new signups in a day, it's too early for me to worry about performance.
#Omar Qureshi
You shouldn't use trigger function in your database - there are many features that can be done by them, but ActiveRecord is database-agnostic and it has callbacks that handle such things that triggers can. Using something that links you to a specific DB system is wrong.
#dmathieu's answer seems to be the best. And you should consider using Factory girl - it's a great tool for populating the DB.

Resources