I have a fairly large DB schema and about 100M rows with I would like to expose to the web, using Rails 3. By exposing to the web, I mean the following:
A REST api (json & xml)
Views to present the data hierarchically
Editors for specific parts of the data
Basically, what I am looking for is a way to run the rails scaffold command with the appropriate arguments automatically. I know that magic_model can do some parts of the reverse engineering itself, but it does not seem to be working with Rails 3.
Is there any tool that can automate the generation of scaffolding?
You could give the following gems a try:
ActiveAdmin
-> Though more of admin framework, it has an appeasing user interface and will aptly satisfy your scaffolding needs.
ActiveScaffold -> A simple auto-scaffold generation framework
I just changed a bit a script of mine:
#!/usr/bin/env ruby
require 'rubygems'
require 'active_record'
require 'active_support'
require 'logger'
require 'fileutils'
ActiveRecord::Base.establish_connection(YAML::load(File.open('database.yml')))
ActiveRecord::Base.logger = Logger.new(File.open('database.log', 'a'))
for table in ActiveRecord::Base.connection.tables
table_class=table.classify
eval("class #{table_class} < ActiveRecord::Base;set_table_name \"#{table}\";end")
columns = []
for column in Kernel.const_get(table_class).columns
columns << "#{column.name}:#{column.type}"
end
puts "rails generate scaffold #{table_class} #{columns.join(' ')}"
end
I tried it on a database of mine (I use only mysql) and I think its output is quite good. Basically it prints the scaffold commands. I don't know if it is a good solution for you but it's a fair starting point IMHO.
You can use reverse_scaffold. It does what the name implies, i.e. Automatically creates the scaffolding from existing table in the legacy database.
You can find it on github:
https://github.com/chrugail/reverse_scaffold (rails 3 version)
There is also a rails 2 version by ahe (the original author)
Related
I am struggling to find a pattern for storing single use user settings (VAT percentage, tag line. Things that are 1 off by nature) in Rails 3. I need to set up global site settings, which have single instances.
Ideally, I want the answer to be a design pattern, rather than a gem or plugin (unless someone knows a gem or plugin that integrates will with Active Admin)
What do you mean by single use settings? Do you mean things like API keys and environment variables?
If so, then a good practice is to use the ENV hash, and set up ENV variables in the environments file (explained below).
Create a .rb file for each individual gem (or arbitrary entity) that needs settings in your config/initializers/ directory. For example, when using stripe, I created config/initializers/stripe.rb shown below:
Rails.configuration.stripe = {
:publishable_key => ENV['STRIPE_PUBLISHABLE_KEY'],
:secret_key => ENV['STRIPE_SECRET_KEY']
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
This sets up initial settings within my stripe gem, and pulls the variable values from the ENV hash.
To set variables in the ENV hash, you can do so within the config/environments directory. In that directory, you will have three different files: config/environments/test.rb, config/environments/development.rb, config/environments/production.rb. Setting variables in the ENV hash(as shown below).
AppName::Application.configure do
# Set Stripe API Key
ENV['STRIPE_SECRET_KEY'] = "sk_test_key"
ENV['STRIPE_PUBLISHABLE_KEY'] = "pk_test_key"
...
end
How about a class for storing your key-value pairs?
class Settings < ActiveRecord::Base
attr_accessible :lookup, :value
def self.VAT
return self.find_by_lookup('VAT')
end
end
Then you can do #vat = Settings.VAT.value or similar. The lookup is your internally defined key. Of course the value column will have to be all the same datatype, but you can handle any necessary transformation in the getter methods (or through subclasses).
I'm trying to perform a query and find 20 records recently created across multiple models using the sunspot_solr gem. Currently it achieves that no problem, but I wanted to add some extra validations for only one of the models that were being searched.
Currently in my User model it lists all new users that were created, but I only want it to list users who have confirmed their email address. I'm using Devise for user authentication and using active record to find all users who have not been confirmed I would do something along the lines of:
User.where("confirmed_at is null")
Or the reverse to test for the opposite. I tried to integrate this with my solr search as so...
Model
#Unless the user being searched hasn't been confirmed...
searchable :unless=> proc { |user| user.confirmed_at == nil } do
time :created_at
time :confirmed_at
end
Controller
#updates = Sunspot.search(Upload,Help,User) do
without(:confirmed_at, nil)
order_by(:created_at, :desc)
paginate page: 1, per_page: 20
end
However this added condition only eliminated user records created after the condition was added to the model. I'm not completely sure how indexing works, but it seems to be caching old information where the newely added conditions weren't being applied. I can confirm this by creating a new user record and I notice immediately it doesn't get indexed until I validate the email address.
What I've tried:
Stopping and restarting server
Stopping server and attempted to stop and restart solr but this produced a PID could not be found error
After reading up a little more on indexing I confirmed my suspicions and found out that I had to re-index my search. To do this I looked at Sunspot readme and found this line:
bundle exec rake sunspot:solr:reindex
I have a bad habit of trying to make use of technologies before I even understand what they do...
I was thinking about giving end users the ability to drop Partial Views (controls) into the information being stored in the database. Is there a way to execute a string I get from the database as part of the Razor view?
Update (I forgot all about this)
I had asked this question previously (which lead me to create RazorEngine) Pulling a View from a database rather than a file
I know of at least two: RazorEngine, MvcMailer
I have a bias towards RazorEngine as it's one that I've worked on but I have a much simpler one at Github called RazorSharp (though it only supports c#)
These are all pretty easy to use.
RazorEngine:
string result = RazorEngine.Razor.Parse(razorTemplate, new { Name = "World" });
MvcMailer
I haven't used this one so I can't help.
RazorSharp
RazorSharp also supports master pages.
string result = RazorSharp.Razor.Parse(new { Name = "World" },
razorTemplate,
masterTemplate); //master template not required
Neither RazorSharp, nor RazorEngine support any of the Mvc helpers such as Html and Url. Since these libraries are supposed to exist outside of Mvc and thus require more work to get them to work with those helpers. I can't say anything about MvcMailer but I suspect the situation is the same.
Hope these help.
I'm working on upgrading an app to Rails 3, and attachment_fu is broken so I'm moving to carrierwave. Is there a systematic process that I can go through to upgrade from attachment_fu to carrierwave? Or a tutorial for it? Right now, I'm more interested in getting everything on the database end right. I'm using the filesystem store option for attachment_fu and carrierwave.
I've found a module, UploaderFu from http://ruby.simapse.com/2011/03/migrate-attachmentfu-to-carrierwave.html that tells carrierwave to use the same directories and filenames as attachment_fu. But it's not the entire answer, just part of it.
For example, in the db, I have a UserImage model, with :filename, :content_type, :size, :width, :height, and :user_id attributes. I added a :user_avatar column, and the following to my model
attr_accessible :user_avatar
mount_uploader :user_avatar, UserAvatarUploader
What exactly gets stored in :user_avatar. Is it just the filename? or something else? Do I just need to write a migration to move the data in :filename (stored like "hello_world.png") to :user_avatar? If that's the case I should just use the original :filename instead of creating a :user_avatar column, right?
The column you mount the uploader on is supposed to store an "identifier" for the uploaded file. By default it's just the filename, but you can override it to be almost anything apart from the ID of the record (because you can't know what that is until after saving).
To override: in your uploader class, add this definition :
def identifier
# This is what gets put in the database column!
model.created_on
end
In this example I've used the created_on attribute from the model. If you want to create your own storage mechanism then you need to be able to uniquely identify files by this identifier so be careful what you choose.
I would suggest renaming the column so it describes the file that's being uploaded (like in the carrierwave example). Then you can always change the identifier from filename to something else later.
Did someone try to integrate puret into rails_admin? I can't make a language switch to edit different translations :(
Changing I18n.locale forces whole rails_admin to use specified locale.
Now I got the solution. The two can work together well. In short:
Delete the pureted column(s) in your model
If you have the column pureted still in your model, rails form helper will bypass puret. That is, if a model called Post has a field called contents to be i18ned, the table posts SHOULD NOT have the column contents.
Actually we should use globalize3 instead. With this you do not need to remove the original column. And puret doens't support nested attributes assignment. globalize3 works very well.