PostgreSQL & DataMapper issues - sql

Been scratching my head for a while on this one and despite trying many variations I cannot see the mistake. After writing the app file, which contains what looks like the correct DataMapper.setup code for using PostgreSQL (?), and upon trying to play around in IRB/PRY, i just get a 'FATAL database not created' message even after i have called 'Song.auto_migrate!', here is my code, can anyone help me get past this? Thanks in advance:
require 'data_mapper'
require 'dm-core' #main DataMapper gem
require 'dm-migrations' #extra DataMapper functionality extension
DataMapper.setup(:default, "postgres://localhost/development")
class Song
include DataMapper::Resource
property :id, Serial
property :title, String
property :lyrics, Text
property :length, Integer
property :released_on, Date
end
DataMapper.finalize
I require the file all fine in irb, then call Song.auto_migrate! and it runs the 'database does not exist' error. What am i doing wrong?

You need to do this in command line:
psql
and then
CREATE DATABASE development;
before even trying to run Data Mapper setup code.

Perhaps you are missing this line: DataMapper.auto_upgrade!

On a side note, remember that auto_migrate! will wipe any existing data, whereas auto_upgrade! doesn't: http://datamapper.org/getting-started.html

Related

uninitialized constant CallsHelper::Active

I'm writing a helper in my Calls view that changes the text of a span depending on a evaluation of a date. When I write the if/else in the view I can make it work but I get the error "uninitialized constant CallsHelper::Active" when trying to access it from my helper.
view code:
<%= status_indicator(call)%>
helper code:
def status_indicator(call)
if call.transfer_date > Time.zone.now
Scheduled
else
Active
end
end
I'm not sure what the error is trying to tell me besides it's not working. Can someone give me a hand and let me know where I'm going wrong?
I want to return strings and not Ruby classes. Putting "" around the strings fixed the problem.

Dashes in property name not getting NoMethodError

I'm using the Linkedin gem to pull profile information for RoR 3.
Gem: https://github.com/pengwynn/linkedin
API Doc: https://developer.linkedin.com/documents/profile-fields#positions
Everything works except when I get to a property with a dash in the name.
<%=position.title %> displays correctly but<%= position.start-date %> return a NoMethodError in Users#show - undefined method start.
I've tried different operations like "startDate", "start_date", quotes around "start-date" but none have worked.
Is there a proper way to escape the dash/hyphen in the property name?
The expression in your ERB will be parsed as subtracting the value of the date variable from the result of a call to the start() method of the position object. Hyphens aren't valid in identifiers within Ruby.
I'm not familiar enough with the LinkedIn gem to suggest a solution, except to say that since it's based on an XML API, you should look for a way to manually pull data out of a tag pair. Most similar gems offer such a method. Also, this is a great case for using IRB as an exploratory tool: fire up an IRB session and see what happens when you call position.methods, after properly creating the position variable of course. My guess would be that you'll see something in that list which suggests an answer.
Looks like it returns a Hashie::Mash which converts keys, with a few extra rules:
https://github.com/pengwynn/linkedin/blob/master/lib/linked_in/mash.rb
You said you'd already tried position.start_date right? That should work. But if not, have you tried position['start-date'] or position['start_date'] one of those two should also work, since it's a Mash.

Systematic way to upgrade from attachment_fu to carrierwave?

I'm working on upgrading an app to Rails 3, and attachment_fu is broken so I'm moving to carrierwave. Is there a systematic process that I can go through to upgrade from attachment_fu to carrierwave? Or a tutorial for it? Right now, I'm more interested in getting everything on the database end right. I'm using the filesystem store option for attachment_fu and carrierwave.
I've found a module, UploaderFu from http://ruby.simapse.com/2011/03/migrate-attachmentfu-to-carrierwave.html that tells carrierwave to use the same directories and filenames as attachment_fu. But it's not the entire answer, just part of it.
For example, in the db, I have a UserImage model, with :filename, :content_type, :size, :width, :height, and :user_id attributes. I added a :user_avatar column, and the following to my model
attr_accessible :user_avatar
mount_uploader :user_avatar, UserAvatarUploader
What exactly gets stored in :user_avatar. Is it just the filename? or something else? Do I just need to write a migration to move the data in :filename (stored like "hello_world.png") to :user_avatar? If that's the case I should just use the original :filename instead of creating a :user_avatar column, right?
The column you mount the uploader on is supposed to store an "identifier" for the uploaded file. By default it's just the filename, but you can override it to be almost anything apart from the ID of the record (because you can't know what that is until after saving).
To override: in your uploader class, add this definition :
def identifier
# This is what gets put in the database column!
model.created_on
end
In this example I've used the created_on attribute from the model. If you want to create your own storage mechanism then you need to be able to uniquely identify files by this identifier so be careful what you choose.
I would suggest renaming the column so it describes the file that's being uploaded (like in the carrierwave example). Then you can always change the identifier from filename to something else later.

Ruby on Rails 3: rails_admin + puret?

Did someone try to integrate puret into rails_admin? I can't make a language switch to edit different translations :(
Changing I18n.locale forces whole rails_admin to use specified locale.
Now I got the solution. The two can work together well. In short:
Delete the pureted column(s) in your model
If you have the column pureted still in your model, rails form helper will bypass puret. That is, if a model called Post has a field called contents to be i18ned, the table posts SHOULD NOT have the column contents.
Actually we should use globalize3 instead. With this you do not need to remove the original column. And puret doens't support nested attributes assignment. globalize3 works very well.

How can I store extra data with a validation error message in Rails 3?

I'm trying to store some additional data along with the standard error message in a custom validator in Rails 3.
For example, (ignoring built-in validators) suppose I wanted to check to see if a post is a duplicate before it's saved. I might write my custom validation method like this:
class Post < ActiveRecord::Base
# prevent duplicate posts
validate do |post|
duplicates = Post.find_all_by_body(body)
errors.add_to_base("Post is a duplicate!") if duplicates.length
# something like this is desired:
# errors.add_to_base("Post is a duplicate",
# :extra => { :duplicates => duplicates })
end
end
This will let the user know there are duplicates, but along with adding the error message I would also like to store the duplicates so they can be displayed to the user. How would I store the list of duplicate posts retrieved during validation such that it is associated with the record's errors for the body field, and available to my view?
A simpler example might be length validation: If a field exceeds its maximum length, how can I store the maximum length along with an error message without simply interpolating it into the message as Rails currently does?
I have not had to do this before, but my first thought is to create a new method on the object called duplicates.
attr_accessor :duplicates
Then in your custom validate method, you can set the duplicates on the object making them available to the view when you render the errors. Notice your current code doesn't change much:
validate do |post|
duplicates = Post.find_all_by_body(body)
errors.add_to_base("Post is a duplicate!") if duplicates.size > 0
end
You would then have to intercept that error in the view manually so that you can print out all the duplicates if the "Post is a duplicate!" error is encountered.
You can pass options to the error but they are only used as substitution in i18n templates. To make a long story short, no you can't store meta-data about your error in the errors hash. If you need such a functionality you'll need to look into the ActiveModel::Errors module in Rails core.
Update:
Another solution could be that instead of pushing a string into error hash, you stuff an instance of your own class, a class which quacks like a string but would be decorated with extra methods and state and such like.