how to call a database table in rails - ruby-on-rails

im trying to reference one of my tables in my rails app but i get the following error
uninitialized constant UsersController::BadgesSashes
im in my user controller, and my table is named badges_sashes (according to my database browser)
i cant do something like...
BadgesSashes.first
in my controller? im using a gem, and i already have a
has_merit
line in my user model. do i need to do anything else? thank you

To reference a table, you need to define a model with the singular version of the name. So if your table is names badges_sashes, than you should create a file app/models/badges_sash.rb:
class BadgesSash < ActiveRecord::Base
end
Bear in mind that usually goes the other way round: You generate a model and it will create a database migration, a class and a unit test for you.
To learn more, you can do an free online course, in which all these things are explained, called Rails for Zombies, or read the book Agile Web Development with Rails or the official guide

Related

Connect rails to existing postgres DB - models not seen by console and controllers

I have a database with several tables, each one containing columns that may not follow the rails naming convention.
Is there a tool existing to create the ActiveRecord models from those tables or do I need to do this at hand, one by one ?
If I create the ActiveRecord model for one table by hand, would this be ok though ? (no hidden DB identifier needed on top of it ?)
UPDATE
I have tried magicmodels but cannot have it working (it has been a while since it was last modified) and does not seem to be compatible with rails 3.2
What I tried then:
- change the database.yml so it points towards my existing Postresql database
- manually create my models such as:
# app/models/user.rb
class User < ActiveRecord::Base
end
- run the console and tried
User.all
=> I end up with an error saying that contant User was not initialized.
Doesn't the console import the model automatically ? Or is that linked to the fact the configuration I did is not correct ?
http://magicmodels.rubyforge.org/magic_model_generator/ may be what you're looking for. I haven't heard of many tools that give this functionality, though, as many rails apps are designed from scratch instead of given a legacy db and then creating the models from that.
You can easily create models by hand and map them to pretty much any db table. Models have a "set_table_name 'name'" that lets you over-write the rails default convention of a single model mapping to a plural db table name.
ActiveRecord works OK with legacy databases. I did a back-end system that didn't use Rails with ActiveRecord as my ORM. "ActiveRecord Without Rails" got me started. "Using ActiveRecord outside Rails" is also useful. Search Google for "use activerecord without rails" and you'll find even more.
You don't need a fully fleshed out model. Just use a base class for the tables you want and ActiveRecord will query the database for what it needs. It won't know about table relationships, but for general queries it'll do fine. Build the relationships as you go and need them.

What is the common way to define models in Rails application?

All of the tutorials I've seen so far for RoR have shown me generating models like:
rails generate User name:string placeofbirth:string
This generates a class for the model, and only actually references an attribute if I apply a validation of some kind.
So my question is, how do I use a 'code' first approach when creating my models. Or is it the rails way to just right down on paper the attributes you want, run the generate command with each attribute you want and it's type, then run the rake db:migrate command?
I'd love some more proven patterns on this subject because so far the way I've seen seems too empty.
Yes, this is the rails way- migration comes first and generates the code and the database- and the model class inspects the database to see what fields are there and make accessible via methods.
You can do gem install annotate_models if you want to get some comments in your model class with the attribute names and types.
See here for an example: https://github.com/ctran/annotate_models
Rails uses an active record pattern for models which basically means that a model object will automatically map each DB column to an attribute so you don't have to specify all attributes in the model. It's a feature, but I agree that it might not be perfect for everyone. If you're using Rails 3 it should be easy to use another ORM of your choice if ActiveRecord's approach doesn't suit you. Here are some alternative ORMs that you could use.
Usually when you are developing some database backed web application, you know the database design(name of the tables, name of the columns in those tables and associations between different tables) beforehand.
Rails, as mentioned by maarons in his answer, uses Active Record pattern. Your models are classes that represent a table in your database, an instance of your model class a row in that table and different attributes of an object represent values under different columns in the same table.
When you create a model, usually, you are creating a class that represents one of the tables in your database. And while you are creating a model, you are also going to create a table in your database. That means knowing the name of the table and columns within that table.
So to answer your question, you must know all the columns, required for the time being, that will be in your tables. And hence available as attribute methods for your model objects. You specify these columns to added in the table in the migration generated by rails generator while generating this model. This is what usually everyone does.
You can take a code first approach by creating a class, without running the rails model generator,under app/models/ but not inheriting it from ActiveRecord::Base. As you move forward in your development, you can generate migrations by $ rails generate migration MigrationName and creating table and adding columns using [add_column][2]to that table as required. Once you have created a table for this model, you will have to inherit that model from ActiveRecord::Base so that you can get all the Rails magic in your application.

Ruby on Rails changes table names for models

Completely new to Rails, I read that it changes your table names because it makes a bunch of assumptions but I'm working with tables that were created pre-rails and are used in a PHP API so I can't change them.
I have a Class created in Rails that references the existing table and of course I get a sql error of table not found because it appends an s at the end of the table name, so I went ahead and put this in my Class definition:
class BookSubjects2title < ActiveRecord::Base
set_table_name "book_subjects2title"
belongs_to :bookSubjects
end
Supposedly, that should take care of the problem from what I've read. Yet it doesn't, it still keeps trying to use the name with the s at the end and I get an error from the rails console. Is there anything I need to do for Rails to read this new config? Should be dynamic no?
Not sure if this is your only issue but
belongs_to :bookSubjects
should never have an 's', use this instead.
belongs_to :book_subject

What kind of information can the Model access in Rails?

In Ryan Bates's first episode on complex forms, he adds the following to a model:
# models/project.rb
has_many :tasks
def task_attributes=(task_attributes)
task_attributes.each do |attributes|
tasks.build(attributes)
end
end
I've never thought about this before, but how does the Project model know what "tasks" of which Project instance? Does that come from the has_many association? Is it like, when the project is running and I'm viewing a Project, that's the "active" object so project.rb knows which Project object we're referring to, so it knows that tasks is really some_current_project.tasks? (I'm obviously grasping at straws here.)
Also, if someone would point me to some reference that explains other questions like this one, I'd really appreciate it.
I hope my question is clear. Please ask for more clarification in comments if needed.
Please note: I know that Active Record handles CRUD actions and that objects correspond to rows in tables, etc. Those are just descriptions of what Active Record is. I'm looking for how it works when the project is running. I also now the constructs MVC, but I can't seem to find a detailed explanation of what information is sent where with respect to Rails.
(Not sure I fully understood your question, feel free to let me know if that's the case.)
A rails model is basically a ruby class that is persisted to a database. So it acts like a normal ruby object for the most part, with some database magic mixed in.
You tell rails which project instance to load (e.g. by providing an id), and it loads the data from the database.
Then, when you call project.tasks is when the magic happens: the Project model has no tasks method, so it will trigger ruby's method_missing method. This will then load the associated records into model instances and provide access to them via a rails object.
Since a project has many tasks, rails knows it should look into the tasks database and load the rows where project_id is equal to the project model's id attribute.
In short, ruby meta-programming and monkey patching possibilities make much of rails' magic possible.
(Edit for question on routing.)
When you want to edit project number 13, you go to a URL that looks something like www.mysite.com/projects/13/edit. If you look at routes.rb in your config directory, you'll see (in Rails3) resources :projects what Rails does is set up all sorts of paths for you. Behind the magic, the edit path looks like
get '/projects/:id/edit' => 'projects#edit'
This basically says "when a user wants to see www.mysite.com/projects/13/edit, send him to the edit action in the projects controller and set the id parameter to the value that's in that place.
Then in your controller, you'll load the appropriate project with
#project = Project.find(params[:id])
In a similar way, you could do this (this is an dumb example):
In routes.rb, put
get '/projects/:id/edit_name/:name' => 'projects#edit'
And then in you controller
#project = Project.find(params[:id])
#project.name = params[:name]
So rails basically uses magic to assign values in the URL to params you can work with in your controller. You can read more about routing here: http://guides.rubyonrails.org/routing.html

custom properties in Rails

I have just started Rails and have a basic question.
I need to add customer properties(like email id etc) so that the Rails app can read them at runtime. How can I do this ?
Can I add them to development.rb and if so how can I read it ?
In java I would have created a properties file and read it from my app.
thank you,
firemonkey
Are you trying to do store and load configuration settings?
It's easy to store configuration settings in a yaml file and load them with initializers - loads better than littering your environment files.
This Railscast: http://railscasts.com/episodes/85-yaml-configuration-file shows you how.
I'm not sure exactly what you are asking. I'm guessing you want an initial set of data in the database that you can access when you actually run the app? If that is so check out this other SO question How (and whether) to populate rails application with initial data
It's a little unclear exactly what you're trying to do, but it sounds like maybe you have a model called Customer and you would like to add some attributes to it, such as email address, id, and so on?
Basically, with Active Record you don't need to do anything special to add a simple attribute (like a string or an integer). Just add a field called "email_address" to your customers table in the database, and all of your Customer objects will automagically get "email_address" and "email_address=" methods (not to mention the Customer class itself getting "find_by_email_address" and other useful methods as well). If you are adding a field containing another model, it's a bit more complicated - add a "something_id" field to the table, and an association to the class definition (eg, "has_one :something"). For more information, see the ActiveRecord api documentation.
You don't have to use any particular means to add the field to your database, but you might want to consider Migrations. Migrations are a convenient way to keep your schema versioned and synchronized across multiple machines.
If you are building your model right now, there's a short cut built in to the generator to add fields. Instead of just saying...
script/generate scaffold customer
...you can say...
script/generate scaffold customer email:string name:string badge_number:integer
...and it will generate all the appropriate fields in your migration, as well as adding them to your generated views.

Resources