Here's my schema file..
ActiveRecord::Schema.define(:version => 20120505115340) do
create_table "clients", :force => true do |t|
t.string "name"
t.string "detail"
t.string "more_detail"
t.string "more_details"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "jobs", :force => true do |t|
t.string "name"
t.integer "number"
t.string "responsible"
t.string "monthly"
t.string "quarterly"
t.string "other"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
end
And here's my migration file's..
class CreateClients < ActiveRecord::Migration
def change
create_table :clients do |t|
t.string :name
t.string :detail
t.string :more_detail
t.string :more_details
t.timestamps
end
end
end
class CreateJobs < ActiveRecord::Migration
def change
create_table :jobs do |t|
t.string :name
t.integer :number
t.string :responsible
t.string :monthly
t.string :quarterly
t.string :other
t.timestamps
end
end
end
In my view file, I have it setup so that is pulls out the client.name and shows it to the user <%= link_to client.name, client_path(client) %>.
However, all im getting back when I create a new entry is /clients/1 instead of the name that I specified in my form.
When I try to migrate the DB nothing happens and then when I try to drop he DB to start afresh it tells me that it does even exist.
If I understand you correctly, you are concerned that your view displays a link to /clients/1 for your newly created object?
This is the default path when using Ruby on Rails, and is what will be produced by the path helper object_path(object) that you are using. This can be customized (see guides on routes.rb). If this is not a problem, then your application is working as intended.
BtW, the number used in the default path refers to the id given to the object. All objects stored using ActiveRecord will automatically get a unique id which can be used to identify the object. Just as the created_at and updated_at columns in your schema, the id column will be created regardless if you explicitly define it in your schema or not.
To reset your database (drop, recreate and migrate to current schema), use the following command:
rake db:reset
EDIT:
<%= link_to client.name, client_path(client) %>
Should result in the following HTML (where CLIENT_NAME is the name attribute of the client)
CLIENT_NAME
Related
I have a little problem with my db schema.
I have create a migration named messages but it was no good so I deleted them for replace by the good messages migration.
But in my schema I have the last messages migration yet.
How it's possible?
rails db:migrate:status:
up 20160924085640 Create conversations
up 20160924090519 Create messages
schema.rb:
create_table "conversations", force: :cascade do |t|
t.integer "sender_id"
t.integer "recipient_id"
end
create_table "messages", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "subject"
t.string "body"
t.integer "recipient_id"
t.integer "sender_id"
end
migration:
class CreateMessages < ActiveRecord::Migration[5.0]
def change
create_table :messages do |t|
t.text :body
t.references :conversation, index: true
t.references :user, index: true
t.boolean :read, :default => false
t.timestamps
end
end
end
routes
resources :conversations do
resources :messages
end
When I try to access to /conversations
I have this error: uninitialized constant ConversationsController
First You should read about rails routes and their correspond action in controller
For Every Route
You should have one controller
one action in controller for desired route
and one view(erb) filw in views
Like for your query
In controller
Create index action
than in views => conversations => index.html.erb
I have two models:
class Order < ActiveRecord::Base
belongs_to :user
has_one :order_type
end
class OrderType < ActiveRecord::Base
belongs_to :order
end
my schema.rb:
create_table "order_types", force: :cascade do |t|
t.string "ort_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "orders", force: :cascade do |t|
t.string "ord_name"
t.date "ord_due_date"
t.integer "user_id"
t.integer "ordertype_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "orders", ["ordertype_id"], name: "index_orders_on_ordertype_id"
add_index "orders", ["user_id"], name: "index_orders_on_user_id"
There is only one-direction association between them. The Order model has a column "ordertype_id" that links to the appropriate order_type.
My question is, what is the best practice to access the ort_name value for each #order in a view.
Currently, I am using:
<p>
<strong>Ord type:</strong>
<% OrderType.where(id: #order.ordertype_id).each do |t| %>
<%= t.ort_name %>
<% end %>
</p>
This solution results in many code repetitions. How I should change that? Can somebody advise, as I am not so experienced yet?
I tried this code, but it did not work:
#orders.order_type
There are many problems which you should address. It's ok to be a beginner, just take yourself time to learn and improve.
Schema
First off, your schema is set up badly. If you want to limit the order type to certain values, you should do this with a validation.
class Order
TYPES = %w[foo bar three four five]
validates :order_type, inclusion: { in: TYPES }
end
This way, you can easily add values in the future, and remove the complexity of adding a new model and its relations.
Column Names
Secondly, you should revise your column names. ord_name and ord_due_date is bad, it leads to ugly calls like order.ord_name. You should drop the prefix ord, it's superfluous.
Both steps would lead to this schema.rb
create_table "orders", force: :cascade do |t|
t.string "name"
t.date "due_date"
t.integer "user_id"
t.string "order_type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Logic placement
My final advice is to never call queries from your view. Logic should always be in the controller / model & passed to the view via instance variables.
This is a big no no in rails:
<% OrderType.where(id: #order.ordertype_id).each do |t| %>
...
<% end %>
In the end, accessing the type is simply accomplished with:
#order.order_type
Update your Order model to this:
class Order < ActiveRecord::Base
belongs_to :user
has_one :order_type, foreign_key: 'ordertype_id`
end
then order_type should be easily accessible:
#order.order_type.ort_name
rails not null / unique in migrations doesn't trigger error :S
class CreateDeditProjects < ActiveRecord::Migration
def change
create_table :dedit_projects do |t|
t.string :name, :null => false
t.string :uid, :unique => true
t.boolean :status
t.timestamps null: false
end
end
end
empty name doesn't trigger error. Neither does duplication of uid.
This is what I see in schema.db
ActiveRecord::Schema.define(version: 20150410105216) do
create_table "dedit_projects", force: :cascade do |t|
t.string "name", null: false
t.string "uid"
t.boolean "status"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
hm, I need to add indexes somewhere I guess? Shouldn't that be automatic?
Not null problem is bogus though.
Rails automatically adds index on id and references and maybe on some other types. If You want to add new index, You can create a migration:
def change
add_index :dedit_projects, :uid, unique: true
end
You can also use validations validates_uniqueness_of and validates_presence_of in models. Although I don't understand why doesn't it work as it is :)
Uniqueness is a property of the index so you need either a separate call to add_index or write it like so
create_table :dedit_projects do |t|
t.string :uid, index: {unique: true}
...
end
I am using the PublicActivity gem and this was created in my database
schema.db
create_table "activities", :force => true do |t|
t.integer "trackable_id"
t.string "trackable_type"
t.integer "owner_id"
t.string "owner_type"
t.string "key"
t.text "parameters"
t.integer "recipient_id"
t.string "recipient_type"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
I am able to track all posts that are happening inside my website by using this inside the post.rb model
class Post < ActiveRecord::Base
include PublicActivity::Model
tracked except: :destroy, owner: ->(controller, model) { controller && controller.current_user }
end
By doing this, I can get the owner_id. What do I need to set recipient: to make it grab the value? Right now recipient_id is nil.
I want to ultimately use something like this in my view <%= link_to activity.recipient_id.name %> to get the name of the recipient where the activity was made to
I'm trying to set it to either the post_id or user_id but I'm getting an undefined local variable or method error.
Here's the table of the model that I'm tracking
create_table "postcomments", :force => true do |t|
t.text "content"
t.integer "user_id"
t.integer "post_id"
t.timestamp "created_at", :null => false
t.timestamp "updated_at", :null => false
t.text "comment_content"
end
I put this in the Model
assuming recipient_id is the user of tracked object. Otherwise change model.user as per your application
tracked recipient: ->(controller, model) { model && model.user }
I am a newbie in rails; my problem is:
I have a table for users, and I need to add more fields...
Where do I put that?
I tried to put it in the migration file, but the schema doesn't change when I run rake db:migrate.
This is in my migration file:
def self.up
create_table :users do |t|
t.string :username, :null => false # if you use another field as a username, for example email, you can safely remove this field.
t.string :email, :default => nil # if you use this field as a username, you might want to make it :null => false.
t.string :crypted_password, :default => nil
t.string :salt, :default => nil
t.string :nombres, :default => nil
t.string :apellidos, :default => nil
t.string :codigo, :default => nil
t.string :fecha, :default => nil
t.string :zona, :default => nil
t.string :institucion, :default => nil
t.string :frecuencia, :default => nil
t.string :pregunta, :default => nil
t.string :respuesta, :default => nil
t.timestamps
end
And the schema is still without new fields
create_table "users", :force => true do |t|
t.string "username", :null => false
t.string "email"
t.string "crypted_password"
t.string "salt"
t.string "nombres"
t.string "apellidos"
t.string "codigo"
t.string "fecha"
t.string "zona"
t.string "institucion"
t.string "frecuencia"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "remember_me_token"
t.datetime "remember_me_token_expires_at"
end
What should I do?
Simple migration
You can use a migration generator:
$> rails g migration add_position_to_users position:integer
then run
$> rake db:migrate
More complex migration
or more complex migration which rails also provide:
$> rails g migration add_body_and_pid_to_users body:string:index pid:integer:uniq:index
$> rake db:migrate
More information about migrations can be found at railsguides
http://guides.rubyonrails.org/migrations.html
I think something we're not mentioning here is adding the code into the migration file.
My steps to add a column go something like this:
# rails generate migration AddFieldName blah:string
Inside the migration file generated:
(btw, this typically looks like: db/migrations/20130330115915_add_field_name.rb)
class AddFieldName < ActiveRecord::Migration
def change
add_column :table_name, :blah, :string
end
end
After making this change, I then run db:migrate. Then, the column is added to the database.