I'm using rails 4.2.5 with mongoid 5.1.0 on windows 10 in dev mode. I have created a model "Signup" but it won't save to MongoDB. I can see that rails connects to MongoDB but no transactions are performned.
What am I missing?
Model code:
class Signup
include Mongoid::Document
field :email, type: String
field :date, type: DateTime, default: ->{ Time.now }
end
Console tests:
irb(main):034:0> s = Signup.create
=> #<Signup _id: 57b9d0436fc5511c04a945ce, email: nil, date: 2016-08-21 16:01:07 UTC>
irb(main):035:0> Signup.count
=> 0
irb(main):036:0> s.save!
=> true
irb(main):037:0> Signup.count
=> 0
irb(main):038:0>
found the solution, I used a dot in the database name in mongoid.yml (project.io) which somehow hindered db creation. I removed it (project_io) and everything is working now as it should.
Related
I have two Mongoid document classes in Rails with a N-N reference relationship, as below:
class Band
include Mongoid::Document
field :name, type: String
field :_id, type: String, default: ->{ name }
has_and_belongs_to_many :tags
end
class Tag
include Mongoid::Document
field :name, type: String
field :_id, type: String, default: ->{ name }
has_and_belongs_to_many :bands
end
Then I create new instances of each one and associate them:
2.0.0p247 :014 > band = Band.new(name: "beetles")
=> #<Band _id: beetles, name: "beetles", tag_ids: nil>
2.0.0p247 :015 > tag = Tag.new(name: "rock")
=> #<Tag _id: rock, name: "rock", band_ids: nil>
2.0.0p247 :016 > band.tags << tag
MOPED: 127.0.0.1:27017 COMMAND database=admin command={:ismaster=>1} (1.3745ms)
MOPED: 127.0.0.1:27017 UPDATE database=band_dev collection=bands selector={"_id"=>"beetles"} update={"$addToSet"=>{"tag_ids"=>{"$each"=>["rock"]}}} flags=[] (0.2341ms)
=> [#<Tag _id: rock, name: "rock", band_ids: ["beetles"]>]
Here a call is made to the database to update the driver class (in this case the "band"). The problem is that neither of these instances were saved and are brand new records!
2.0.0p247 :017 > band.new_record?
=> true
2.0.0p247 :018 > tag.new_record?
=> true
So why to perform a db roundtrip for an unsaved document? Is there a setting where I can turn this off?
Version Info:
mongoid (4.0.0 80ed36f)
moped (1.5.1)
origin (1.1.0)
bson (1.8.6)
bson_ext (1.8.6)
rails (4.0.0)
OS: Ubuntu 12.04 LTS
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
.new() method does not save it.
use .create() instead.
band=Band.new() does create a new object of Band class, but it does not persist.
When you push the relation using << method, the relation between those 2 new objects created.
So, when you query, those 2 objects are already in N-N relationship.
However, that is object living in this code execution , not really persisted as data.
To save it in your mongodb, you need to define the first object with .create() instead of new().
It may look like
band=Band.create(name:"beetles")
band.tags << Tag.new(name:"rock")
I'm using accepts_nested_attributes_for in Rails 2.3.5 and find it does unnecessary validations on save.
In my application I have thousands of records so this is a problem.
To ilustrate this, I prepared a simple example.
class Language < ActiveRecord::Base
has_many :phrases
accepts_nested_attributes_for :phrases
end
class Phrase < ActiveRecord::Base
validates_presence_of :value
belongs_to :language
def before_validation
print "\nValidating: #{self.value}\n"
end
end
$ script/console
Loading development environment (Rails 2.3.5)
>> lang = Language.first
=> #<Language id: 1, name: "Italiano">
>> lang.phrases
=> [#<Phrase id: 7, value: "Buona notte", language_id: 1>,
#<Phrase id: 10, value: "Ciao", language_id: 1>,
#<Phrase id: 11, value: "Prego", language_id: 1>]
>> lang.phrases_attributes = [{:id => "7", :value => "Buon giorno"}]
=> [{:value=>"Buon giorno", :id=>"7"}]
>> lang.save
Validating: Buon giorno
Validating: Ciao
Validating: Prego
=> true
As this example shows it is validating not only the child that was added, but all other children.
Am I missing something?
How can I avoid doing all these validations?
As i indicated earlier, this is a real handicap for a large app.
After a suggestion I received from a Jason King of the SDRuby group I tried updating to 2.3.18.
That solved the problem
I want to update_attributes and than check if information is changed
You can simply pass this code to rails console in existing rails + mongoid project
class TestModel
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
end
test = TestModel.new({:name => "name 1"})
test.save()
=> true
test
=> created_at: 2012-11-14 13:48:26 UTC, updated_at: 2012-11-14 13:48:26 UTC
test.changed?
=> false
test.name_changed?
=> false
test.update_attributes({:name => "name 2"})
=> true
test.changed?
=> false
test.name_changed?
=> false
test
=> created_at: 2012-11-14 13:48:26 UTC, updated_at: 2012-11-14 13:49:23 UTC
Am I doing something wrong or this is a bug?
Its perfectly logic.
Dirty methods are meant to be used to check if an object has changed before it's saved. By definition a persisted object has no pending changes.
You should do:
test.assign_attributes(attributes)
test.changed? #=> true
test.save
See method definition.
I've using the Cloudinary gem, which up until now has worked fine as an embedded Photo model in Mongoid:
class PhotoUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave
def public_id
return model.id
end
end
class Photo
include Mongoid::Document
include Mongoid::Timestamps
embedded_in :place#, :inverse_of => :photos, :autosave => true
mount_uploader :image, PhotoUploader
#...
end
However, after upgrading to Mongoid 3, getting the image URL no longer works. Consider this Photo model:
1.9.3p194 :019 > p
=> #<Photo _id: 507bc3c82a450b14bd00e00a, _type: nil, created_at: 2012-10-15 08:05:28 UTC, updated_at: 2012-10-15 08:05:28 UTC, image_filename: nil, caption: nil, original_url: "http://www.reactionny.com//images/assets/101755_316529.JPG", image: "v1350288333/507bc3c82a450b14bd00e00a.jpg">
1.9.3p194 :020 > p.image
=> /assets/fallback/default.png
1.9.3p194 :021 > p.image_url
=> "/assets/fallback/default.png"
1.9.3p194 :022 > p['image']
=> "v1350288333/507bc3c82a450b14bd00e00a.jpg"
Why is it no longer returning the fully-qualified Cloudinary URL, in the form http://res.cloudinary.com/XXXXXX/image/upload/v1350288842/507bc5ca2a450b14bd00e896.jpg?
It seems that carrierwave-mongoid changed the name of the field in which the image is saved from yyy to yyy_filename.
In your model inspection printing you can see that image_filename is nil.
The integration with the Cloudinary GEM and CarrierWave seems to be working fine, but you need to migrate your model.
The relevant field used to be called 'image' and it's now called 'image_filename'. You should probably update your model to use the new field name and copy all values.
Another possible solution would be to specifically set the attribute name using mount_on:
mount_uploader :image, PhotoUploader, mount_on: :image
I have an Account model:
class Account
include Mongoid::Document
include Mongoid::Timestamps
referenced_in :user
end
and User:
class User
include Mongoid::Document
include Mongoid::Timestamps
...
references_one :account
...
end
And the following scenario(i try to set reference_one association):
Scenario: Client views his account
Given the following accounts:
| user_id |
| 1123322131 |
.....
And the following step:
Given /^the following accounts:$/ do |class_name, table|
table.hashes.each do |attributes|
Account.create(attributes)
end
end
When I try to run cucumber, I always get an error:
illegal ObjectId format (BSON::InvalidObjectId)
./features/step_definitions/common_steps.rb:7:in `block (2 levels) in <top (required)>'
./features/step_definitions/common_steps.rb:6:in `each'
./features/step_definitions/common_steps.rb:6:in `/^the following accounts:$/'
features/manage_accounts.feature:8:in `And the following accounts:'
full version of backtrace: https://gist.github.com/433ea982d876e1b1fa27
I use: Rails 3.0.3, Ruby 1.9.2, cucumber 1.9.4, machinist 2, mongoid. My Gemfile
What did I do wrong?
UPD. No so obviously behaviour:
> a = Account.create :user_id => "123"
BSON::InvalidObjectId: illegal ObjectId format
> a = Account.create :user_id => 123
=> #<Account _id: 4ceedf055e6f991aef000005, created_at: 2010-11-25 22:11:17 UTC, updated_at: 2010-11-25 22:11:17 UTC, user_id: 123>
> a = Account.create :user_id => "4ceede9b5e6f991aef000007"
=> #<Account _id: 4ceedf1b5e6f991aef000006, created_at: 2010-11-25 22:11:39 UTC, updated_at: 2010-11-25 22:11:39 UTC, user_id: BSON::ObjectId('4ceede9b5e6f991aef000007')>
This could solve your problems:
Given /^the following accounts:$/ do |class_name, table|
table.hashes.each do |attributes|
User.create(attributes).create_account
end
end
Are you using a custom primary key for User? It seems that Mongoid is expecting a normal BSON::ObjectId like BSON::ObjectId('4ceeaf282b2d3a2ab0000001' but you are passing a plain string like 1123322131. In general, you have to be careful when trying to create a record and its associations at the same time