(Object doesn't support #inspect) - ruby-on-rails-3.1

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.

Related

Rails Newby: Strong parameters in Rails 5 not letting specified parameter Through - HABTM

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.

undefined method `each' for true:TrueClass when adding boolean values

In the console of my application I get "undefined method `each' for true:TrueClass" when attempting to set a Boolean to true or false.
For instance if I do
Man.create(guy: true) # or
Man.create(:guy => true) # etc
I have not worked on this application for several months and I believe everything was working fine before I stopped work on it. I am pretty new to Ruby and have limited programming knowledge so any help is much appreciated. creating rows and providing only string or integer values works fine. I am using an SQLite3 database if that matters.
guy is a Boolean
class AddMan < ActiveRecord::Migration
def change
create_table :men do |t|
t.boolean :guy
t.boolean :girl
t.boolean :dude
t.boolean :lady
t.boolean :albert
t.timestamps
end
end
end
class Man < ActiveRecord::Base
has_many :guys
has_many :girls
end
This:
has_many :guys
has_many :girls
assumes, by Rails convention, the presence of Integer columns :guy_id and girl_id, which should be foreign keys into the guys and girls tables, respectively. These are not present in your schema, so I assume that's the root cause of the error you're seeing.
In general, try avoiding column names that may be in conflict with other models (I assume you have models named Guy and Girl. Try renaming your boolean columns to something like is_guy and is_girl.
From your Man Model I assumes that you have guys and girls different tables. And from your console it seems that you want to assign value to Man table's guy attribute.
If this is the case then you can assign value to your Man table's guy attribute like
man = Man.new
man.guy = true

NameError when assigning instance of model to reference property

I'm unable to assign a model instance to a reference property of another model. Relevant code is below:
module Blog::Models
class Post < Base; belongs_to :user, dependent: :destroy end
class User < Base; has_many :posts end
...
class BasicFields < V 1.0
def self.up
create_table User.table_name do |t|
...
end
create_table Post.table_name do |t|
...
t.references :user
end
end
...
end
end
module Blog::Controllers
...
class PostEditN
...
def post(post_num)
#post = Post.find(post_num)
#user = User.find(#input.user)
...
#post.user = #user # Error thrown: NameError at /post/edit/1 uninitialized constant User
# #post.user_id = #user.id << This is my currently working solution
#post.save
redirect PostN, post_num
end
end
...
end
...
When I assign something to #post.user using Camping in console mode, it is successful, but I can't seem to accomplish the same behavior in the controller otherwise. I made do by simply assigning the #user.id to the user_id property of the Post instance. However, I would like to figure out why the alternate method works in the Camping console and not when I'm simply running the webserver.
My best guess is that this is a problem with namespaces. In the code you show Useris actually Blog::Models::User. In your controller the context is Blog::Controllers. Have you tried changing the code in the controller to?
#post = Blog::Models::Post.find(post_num)
#user = Blog::Models::User.find(#input.user)
...
I was able to resolve my issue. Seems when I was creating new Post records, I was not initializing the User. Thus, when assigning #post.user it would complain that the user property was uninitialized. The only problem I see is that an operation was attempted to be made on an oprhan Post record, which is invalid data according to the relationship with User.

Rails model singular format

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

How can I create a field using the id from the same row in ActiveRecord Ruby

-----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

Resources