This is more a question to see if an error has occurred when creating a model in my app.
I have created a model in the usual way
rails g model Media
Now i thought that this would actually create the following
class CreateMedias < ActiveRecord::Migration
def change
create_table :medias do |t|
t.timestamps
end
end
end
but it didnt it created
class CreateMedia < ActiveRecord::Migration
def change
create_table :media do |t|
t.timestamps
end
end
end
I thought the model represented as single media but the database consists of many medias. Why would the migration not change to medias? Is it best to delete this model and try it again or is this normal behaviour?
Thanks
Media is the plural of Medium.
The clean way would be to have a Medium model and Media for table name.
Media as data type is not countable. So you could add inflections.
Just put further code into your config/initializers/inflection.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.uncountable 'media'
end
see docks here
Related
I'm new to rails, and I'm currently trying to develop an API based app using Rails 5, on one of my controllers I have a function to filter the allow parameters like so
def provider_params
params.require(:provider).permit(:name, :phone, :email, :website, :address, :provider_id, :bio, :specialty_ids => [])
end
Then posting from Paw I noticed that the arguments that are not attributes of the table are no included in provider_params, the parameter I'm supposed to receive is an array, which is defined by a HABTM relation-ship.
This is how my models look like
specialty.rb
class Specialty < ApplicationRecord
has_and_belongs_to_many :providers
end
provider.rb
class Provider < ApplicationRecord
has_and_belongs_to_many :specialties
end
And this is how the join table was created via migration
class CreateProvidersSpecialties < ActiveRecord::Migration[5.0]
def change
create_table :providers_specialties, :id => false do |t|
t.integer :provider_id
t.integer :specialty_id
end
add_index :providers_specialties, :provider_id
add_index :providers_specialties, :specialty_id
end
end
The JSON I'm posting
{
"name": "the name",
"specialty_ids": [
1,
2
]
}
So as I mentioned, the array specialty_ids doesn't seem to be coming through, and even if it did, I suspect there's still something else I need to do in order for rails to insert the content of specialty_ids in the ProvidersSpecialties Table
So the problem was finally solved by removing the requir call from the method provider_params, since I wasn't wrapping the json-payload in a provider key. Apparently once you add the require(:key) call you would only be able to add parameters that belong to the Model, which is weird since an error should be raised when the key is not present, what was the case with my payload, lacking the provider key.
I want to add new table using rails migration:
**table_name** users_location_track
**columns** id (primary key, auto increment serial),
user_id (reference to users), location_info (string),
creation_time(time-stamp)
please suggest procedure and code I am new to rails?
In Rails You need to write a command like below:
rails generate migration CreateUserLocationTrack user_id:integer location_info:string
you don't need creation_time as created_at is created by default.
For more information, please follow rails guide.
thank you for criticizing.
Finally I got my answer:
Here's the solution for whoever want in future.
first go to project directory then run following command
rails generate migration add_user_lat_long
and then a migration file will be generate then you can edit in following style:
class AddUserLatLong < ActiveRecord::Migration
def self.up
create_table :users_location_track do |t|
t.string :location_info
t.references :user
t.timestamps
end
add_index :users_location_track, :user_id, :name =>'index_user_lat_longs_on_user_id'
end
def self.down
drop_table :users_location_track
end
end
I am trying to create an activity stream so my model looks like
class CreateFeeds < ActiveRecord::Migration
def change
create_table :feeds do |t|
t.integer :item_id
t.string :item_type
t.integer :user_id
t.timestamps
end
end
end
class Feed < ActiveRecord::Base
belongs_to :user
belongs_to :item, polymorphic: true
end
I have added this to my post controller
feed_item #post
and this to my application controller
def feed_item(item, action = params[:action])
current_user.feeds.create! action: action, item: item
end
I am displaying my post content like
= feed.item.text
my problem is when I call
= link_to "delete", feed.item, method: :delete
I delete the feed item but the reference to the item remain in the database and I get
error: missing template "delete"
unless I add if present?
How can I this reference to an item?
Your code is simply deleting the item, with no impact on the feed. I think you need to either:
Explicitly clear the item_type and item_id references in feed (e.g. by implementing a remove_item method in your Feed controller and model), or
If your domain would allow for it, change your belongs_to association to a has_one association, with corresponding changes to your database. In that case, deleting the item wouldn't require any changes to the associated feed.
As an aside, it's unusual to keep your migration in with your model definition. The migration should really be in a separate file.
-----UPDATE-----
Well, seems that the problem was in last.id. When database is created works OK, but when not fails. Now the question is different: How can I create a field using the id from the same row?
--------ORIGINAL------
I'm working with active record in pure ruby (without Rails), and I'm literally getting crazy with this.
This is my code
class Enviroment < ActiveRecord::Base
#self.table_name = 'enviroments'
self.connection.create_table(:enviroments, :force=>true) do |t|
t.column :name, :string, :default=>'env-'+ (last.id-1).to_s
t.column :ssh, :string, :default=>nil
end
end
and here the error:
ActiveRecord::StatementInvalid: Could not find table 'enviroments'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.2.3/lib/active_record/connection_adapters/sqlite_adapter.rb:465:in `table_structure'
if I useself.table_name = 'enviroments' still not working. I've updated the gems and neither.
I'm newbie with ruby and databases, but I can't understand this problem, I think this same code worked in the past :S
Your code to create the table (very odd to have that in the model by the way) is calling last.id, and of course to call last the table must already exist.
Because you're passing :force => true to create_table you'll actually destroy the table if it already exists.
You could probably make your code work if you stashed the value of last.id in a local variable before the call to create_table but I don't understand why you are creating tables like this.
Finally, this was my solution:
class Enviroment < ActiveRecord::Base
after_create :create_default
private
def create_default
if name == nil
s = 'env-' + self.id.to_s
self.name = s
self.save
end
end
end
class CreateSchema < ActiveRecord::Migration
create_table(:enviroments, :force=>true) do |t|
t.column :name, :string, :default=>nil
t.column :ssh, :string, :default=>nil
end
I have a simple case, involving two model classes:
class Game < ActiveRecord::Base
has_many :snapshots
def initialize(params={})
# ...
end
end
class Snapshot < ActiveRecord::Base
belongs_to :game
def initialize(params={})
# ...
end
end
with these migrations:
class CreateGames < ActiveRecord::Migration
def change
create_table :games do |t|
t.string :name
t.string :difficulty
t.string :status
t.timestamps
end
end
end
class CreateSnapshots < ActiveRecord::Migration
def change
create_table :snapshots do |t|
t.integer :game_id
t.integer :branch_mark
t.string :previous_state
t.integer :new_row
t.integer :new_column
t.integer :new_value
t.timestamps
end
end
end
If I attempt to create a Snapshot instance in rails console, using
Snapshot.new
I get
(Object doesn't support #inspect)
Now for the good part. If I comment out the initialize method in snapshot.rb, then Snapshot.new works. Why is this happening?
BTW I am using Rails 3.1, and Ruby 1.9.2
This is happening because you override the initialize method of your base class (ActiveRecord::Base). Instance variables defined in your base class will not get initialized and #inspect will fail.
To fix this problem you need to call super in your sub class:
class Game < ActiveRecord::Base
has_many :snapshots
def initialize(params={})
super(params)
# ...
end
end
I had this symptom when I had a serialize in a model like this;
serialize :column1, :column2
Needs to be like;
serialize :column1
serialize :column2
I ran into this issue when I used an invalid association name in a joins.
For example,
Book.joins(:authors).first
Should be
Book.joins(:author).first
Assuming a Book model belongs_to an Author model.
This can also happen when you implement after_initialize, particularly if you are attempting to access attributes which were not included in your select. For instance:
after_initialize do |pet|
pet.speak_method ||= bark # default
end
To fix, add a test for whether the attribute exists:
after_initialize do |pet|
pet.speak_method ||= bark if pet.attributes.include? 'speak_method' # default`
end
I'm not sure exactly why, but I got this error when I accidentally misspelled 'belongs_to' as 'belong_to' in the associated class definition.
I believe you forgot to
rails db:migrate
Try calling .valid? on the new object to see if you can get a more helpful error.
In my case, I got this error from a block of code that creates a new instance of one of my models and assigns values to its fields. It turns out that my code was assigning a value to one of the fields that Rails couldn't match with that field's type. Calling valid? on the new object gave me a more helpful error (undefined method `to_f' for #<MatchData...).
I ran into this problem after trying to integrate devise authentication with an existing User model, I solved it by running command below:
$spring stop
Don't know the exact cause but hope it helps someone.
This is a misleading and nonspecific error. For instance, I just got it because I made a scope like this:
scope :posted, -> { where('posted_on_date <= ?', Date.today) }
when it should have been:
scope :posted, -> { where('post_on_date <= ?', Date.today) }
In my case, this was due to my mistakenly using the posted_on_date attribute.
I get this problem if the model contains an after_find.
The same error if you put the attribute type wrong:
attribute :publicar, :integer, default: true
instead of
attribute :publicar, :boolean, default: true
I was getting this error when running an ActiveRecord .where clause/method.
It was simply because there was a typo in the column name. Once I fixed the typo the query worked exactly as expected.
Wrong:
Package.where(scrape_nunber: 2)
Right (fixed typo in column name, and it works now):
Package.where(scrape_number: 2)
Just double check there isn't a typo in your column name(s) in the where clause.