NoMethodError: Undefined method `first_or_create' for "foo":String - ruby

I have used this method before in a Sinatra application with Datamapper without any troubles.
Now it doesn't seem to work. Any ideas appreciated.
My test:
scenario 'add hashtags to posts' do
visit '/'
add_post('Stacca',
'Hello! out there',
%w(foo bar))
post = Post.first
expect(post.hashtag.map(&:text)).to include('foo')
expect(post.hashtag.map(&:text)).to include('bar')
end
My server
post '/posting' do
username = params['username']
message = params['message']
hashtag = params['hashtag'].split(' ').map do |hashtag|
hashtag.first_or_create(text: hashtag)
end
Post.create(username: username, message: message, hashtag: hashtag)
redirect to ('/')
end
My Models:
class Post
include DataMapper::Resource
property :id, Serial
property :username, String
property :message, String
has n, :hashtag, through: Resource
end
and:
class Hashtag
include DataMapper::Resource
has n, :posts, through: Resource
property :id, Serial
property :text, String
end
Thank you

This line:
hashtag.first_or_create(text: hashtag)
should be:
Hashtag.first_or_create(text: hashtag) # uppercase!
Else, you are just trying to call a non existing "first_or_create" method on the String ("foo") you got from the scenario. 'Hashtag' is your class, 'hashtag' is your (String) variable.

Hashtag.first_or_create(text: hashtag)
Hashtag should have been a class
i.e. you missed the capital

Related

Ruby Datamapper: retrieving record using param in url path returns null - sometimes

I'm creating a Sinatra App using Datamapper.
With the following route, I'm attempting to print the record for an id. So localhost:9292/api/1 should return results for id=1
inside
get '/api/:id' do
I tried a couple things with varied results:
thing = Thing.get(params[:id])
thing.to_json
end
outputs 'null', but:
id_param = params[:id]
id_param
end
prints 1 as expected, and:
hardcoded_thing = Thing.get(1)
hardcoded_thing.to_json
end
correctly prints the hardcoded db record with id=1. So I must be losing it..
Any ideas?
Thanks!
For reference, here's my model:
class Thing
include DataMapper::Resource
include BCrypt
property :id, Serial, :key => true
property :created_at, DateTime
property :updated_at, DateTime
property :name, String, :length => 50
property :cafe_topic, Text
end
Try this:
get '/api/:id' do |id|
thing = Thing.get(id)
thing.to_json
end

Ruby datamapper associations

I am just learning Ruby and datamapper, I have read the docs about associations from the official DataMapper site, but I still have two problems.
First whenever I add associated object, I can not see it when displaying all objects.
I have test class like:
class Test
include DataMapper::Resource
property :id, Serial
property :name, String
has 1, :phonen, :through => Resource
end
And then phonen class like:
class Phonen
include DataMapper::Resource
property :id, Serial
property :number, String
belongs_to :test
end
Then I am creating those 2 objects
#test = Test.create(
:name => "Name here"
)
#phone = Phonen.create(
:number => "Phone number"
)
#test.phonen = #phone
#test.save
And I want to display them like that (I want to return json)
get '/' do
Test.all.to_json
end
What am I doing wrong? maybe its something with the to_json...
I honestly don't know..
But I have one additional question to this topic, lets say I managed to connect those two classes, if I display JSON will I get Phonen { } or just inside class { }?
I know its probably very easy question, but I can't figure it out. That's why I decided to ask you guys. Thanks for help
Test.all
Is returning an active record association in array form, not a hash, when you try to convert to json it's failing.
You can try:
render json: Test.all
As asked in this question:
Ruby array to JSON and Rails JSON rendering

Using validates_with with ruby and mongoid

I'm new to ruby and mongoid. I need to use validates_with and below is the code I have
class ValidatorClass < ActiveModel::Validator
def validate(record)
if record.name == ""
record.errors.add(:name, "An error occurred")
end
end
end
class Person
include Mongoid::Document
include Mongoid::Timestamps::Created
include Mongoid::Timestamps::Updated
include Mongoid::Versioning
include ActiveModel::Validations
field :id, type: Integer
field :name, type: String
field :age, type: Integer
validates_with ValidatorClass, :on => :create
end
But when I create the model with following code:
Person.create(id: 5, name: "", age: 50)
I don't get the error thrown. I'm not using Rails. I'm using just ruby with mongodb. Could anybody out there help me? Thanks in advance.
From the documentation, can you try adding this line in class Person:
include ActiveModel::Validations
http://api.rubyonrails.org/classes/ActiveModel/Validator.html
You dont have to include ActiveModel::Validations on your class
Try changing your validation class to use the code bellow:
class ValidatorClass < ActiveModel::Validator
def validate(record)
if record.name.blank?
record.errors.add(:name, "An error occurred")
end
end
end
Hope it helps!
Please try this:
class ValidatorClass < ActiveModel::Validator
def validate(record)
if !record.name.present?
record.errors.add(:name, "An error occurred")
end
end
end

DataMapper save fails but with no errors

When I try to modify and then save a model using DataMapper I get a SaveFailure exception but no errors.
Specifically I see this message:
"MonthlyBill#save returned false, MonthlyBill was not saved"
This is the code doing the saving:
post '/monthly_bills' do
with_authenticated_user do |user|
description = params[:description]
expected_amount = params[:expected_amount]
pay_period = params[:pay_period]
monthly_bill = MonthlyBill.new(:description=>description, :expected_amount=>expected_amount, :pay_period=>pay_period)
user.monthly_bills << monthly_bill
user.save
end
The User model:
class User
include DataMapper::Resource
property :id, Serial
property :email_address, String
property :password, String
has n, :monthly_bills
has 1, :current_pay_period
end
The MonthlyBill model:
class MonthlyBill
include DataMapper::Resource
property :id, Serial
property :description, String
property :expected_amount,Decimal
property :pay_period, Integer
belongs_to :user
end
What is the issue and, more importantly, how can I get DataMapper to tell me more specifically what is wrong?
Hmm - those capitalised properties look worrying to me. I would do...
has n, :monthly_bills
has 1, :current_pay_period #do you really have a CurrentPayPeriod model?!
And then try:
monthly_bill = MonthlyBill.new(:description=>description,:expected_amount=>expected_amount, :pay_period=>pay_period, :user=>user)
monthly_bill.save

Error happens when I read items in DataMapper

class List
include DataMapper::Resource
property :id, Serial
property :name, String
property :items, String
end
List.auto_migrate!
get '/:id' do
#list = List.all(:id => params[:id])
#items = #list.items
erb :show
end
I get undefined method `items' for #. Any ideas?
You fetch a collection of lists instead of a single list instance, that's why you get the error. I believe you want to do:
#list = List.get(params[:id])

Resources