Modify data structure of CarrierWave image uploader - ruby-on-rails

I'm using the ruby gem CarrierWave to handle images on my rails app, which is a mobile backend API. Is there a way to store the image url and thumb url directly on the parent object?
This is the default behavior, shown in the post object's json. Notice the nested JSON:
{
created_at: "2012-11-17T18:24:04Z",
description: "this is the content",
id: 6,
user_id: 1,
picture: {
url: "/uploads/entry/picture/6/wtf_llama.jpeg",
thumb: {
url: "/uploads/entry/picture/6/thumb_wtf_llama.jpeg"
}
},
updated_at: "2012-11-26T08:16:43Z"
}
What I'd like to see:
{
created_at: "2012-11-17T18:24:04Z",
description: "this is the content",
id: 6,
user_id: 1,
picture_url = "/uploads/entry/picture/6/wtf_llama.jpeg",
thumb_url = "/uploads/entry/picture/6/thumb_wtf_llama.jpeg"
updated_at: "2012-11-26T08:16:43Z"
}
Is this possible?

Why storing those paths in models? Improve response (view or controller), not persistence layer (model). I believe it's easiest to achieve with as_json. Either add picture_url methods to model or merge additional entries to your final hash.

Related

Subnodes in a json template

I have a template for json using the JB gem: index.json.jb
https://github.com/amatsuda/jb
It outputs all the settings with some attributes per record.
Settings also have a metadata field, which is a postgres jsonB field. I'd like to loop through the metadata fields contents and add it to my json template. I've tried all sorts of ways and I can't figure out how to do this.
json = {}
json[:settings] = #settings.map do |setting|
{
id: setting.id,
category: setting.category,
created_at: setting.created_at,
updated_at: setting.updated_at,
notes: setting.notes,
name: setting.full_name,
setting.metadata.map do |meta|
{
meta[0]: meta[1]
}
end
}
end

carrier wave uploaded image should not exist but does in rails

I have a model called "Profile" and one of the attributes is called "pic". In the console, when I do:
User.first.profile
The following is returned.
=> #<Profile id: 64, created_at: "2014-06-19 15:59:41",
updated_at: "2014-06-19 15:59:41", user_id: 24,
description: "fds aslkjd aslkfjhas dlkjashdf lajkdshf al...",
rate: nil, pic: nil >
As you can see, the "pic" attribute is nil because I never uploaded a picture. I am trying to write several "if statements" to distinguish whether or not the picture exists. For example:
#profile = User.find(24).profile.first
if #profile.pic
I've also tried:
#profile = User.find(24).profile.first
if #profile.pic.exists?
All of these evaluate to true, which should not happen since a picture has never been uploaded.
I've also tried:
#profile = User.find(24).profile.first
if #profile.pic.nil?
and for some reason that evaluates to false.
When I run in the console:
=> #<PicUploader:0x007ff8abeb8560 #model=#<Profile id: 64,
created_at: "2014-06-19 15:59:41", updated_at: "2014-06-19 15:59:41",
user_id: 24, description: "fds aslkjd aslkfjhas dlkjashdf lajkdshf al...",
rate: nil, pic: nil>, #mounted_as=:pic>
I don't know where that is coming from. How do I write an "if statement" for whether or not the image exists that will actually return false like it should?
Thanks.
With carrierwave, you should use either the question-method of your attribute, pic?, or you can use blank?/present?:
#profile.pic.present?
# => false
#profile.pic?
# => false
#profile.pic.blank?
# => true

How to get user object with belongs_to in ember js?

I have two models Recipe and User. I can't get the user object in recipe. What am I doing wrong?
App.Recipe.find(1).get('title') // Returns "recipe01 title". All works fine.
App.Recipe.find(1).get('user') // Returns null
user.js.coffee
App.User = DS.Model.extend
email: DS.attr('string')
recipes: DS.hasMany('App.Recipe')
recipe.js.coffee
App.Recipe = DS.Model.extend
user: DS.belongsTo('App.User')
title: DS.attr('string')
my json array
{
recipe: {
id: 1,
title: "recipe01",
user: {
id: 1,
name: "ejiqpep",
email: "ejiqpep#gmail.com",
}
}
}
By default Ember Data expects dependent records to be referenced by key. Then you can either sideload the extra records or let Ember lazy load them from their API endpoint.
{
recipe: {
id: 1,
title: "recipe01",
user_id: 1
},
user: {
id: 1,
name: "ejiqpep",
email: "ejiqpep#gmail.com"
}
}
However, you can also instruct the Adapter that the records are embedded.
There are two types of embedded record loading embedded: 'always', where Ember will both receive and send any changes with the objects embedded.
App.Adapter.map 'App.Recipe',
user:
embedded: 'always'
Or embedded:'load' where Ember will load embedded objects from JSON but will save changes back to the API as separate objects.
App.Adapter.map 'App.Recipe',
user:
embedded: 'load'
Which of the three options you'd like to take is up to you.
Embedded objects have only recently been implemented and there are a couple of issues around them (see the Ember-Data issues on Github), but will work without any changes to your existing server.

Rails 3 Serialization issue

I have an application that was working fine with ror 2.3.x. I am having trouble upgrading to Rails 3 with serialization.
The code looks like this
class PaymentTransaction < ActiveRecord::Base
serialize :response
end
The response is supposed to contain the ActiveMerchant::Billing::Response. With rails 3 for some reason its being save as string.
=> #<PaymentTransaction id: 11, order_id: nil, amount: nil, mode: nil, payment_profile_id: nil, response: "#<ActiveMerchant::Billing::Response:0x1051aec98>", created_at: "2010-11-07 04:06:03", updated_at: "2010-11-07 04:24:58", result: "pending", payee: nil, login_id: nil, transaction_key: nil>
I didn't any notes on serialization in any other blogs talking about upgrade. Any thoughts?
The Rails 2 explanations for using serialization did not work in Rails 3 for me unless I also specified the type of the serialized object in the serialize call. For example:
serialize :response, Array
After specifying array the functionality worked as expected.
Further documentation here:
http://api.rubyonrails.org/classes/ActiveRecord/Base.html
under "Saving Arrays [...]"
There was a small change in rails 3 which have an effect: https://github.com/rails/rails/commit/c1d73270717f30498f8f4d55d6695509107c2834
There are two good blog posts about serialization here:
http://www.simonecarletti.com/blog/2010/04/inside-ruby-on-rails-serializing-ruby-objects-with-json/
http://www.skorks.com/2010/04/serializing-and-deserializing-objects-with-ruby/

Can I scope dynamic attribute-based finders to an object?

Don't mind me, I fricked up my attribute names :(
This is entirely possible, using the exact syntax I used - you just need to be able to spell!
I can't seem to get this to work, and it seems like a common enough scenario that there must be a solution, but I'm not having any luck with the correct terminology to get a helpful Google result.
I want to do this:
u = User.first
u.clients.find_or_create_by_email('example#example.com')
With the effect that a new Client is created with user_id = u.id.
Can I get the nice dynamic finders through a has_many relationship? If not, why?
Thanks :)
This
u = User.first
u.clients.find_or_create_by_email('example#example.com')
works if you have has_many relationship set. However, it won't raise validation error if you have any validations set on your Client object and it will silently fail if the validation fails.
You can check the output in your console when you do
u.clients.find_or_create_by_email('example#example.com') # => #<Client id: nil, email: 'example#example.com', name: nil, user_id: 1, another_attribute: nil, active: true, created_at: nil, updated_at: nil>
and the user_id will be set but not the id of client because the validation has failed and the client is not created
So this should create the client only if you pass all the required attributes of client object and the validation for client object has passed successfully.
So lets say your client model has validation on name as well apart from email then you should do
u.clients.find_or_create_by_email_and_name('example#example.com', 'my_name') #=> #<Client id: 1, email: 'example#example.com', name: 'my_name', user_id: 1, another_attribute: nil, active: true, created_at: "2009-12-14 11:08:23", updated_at: "2009-12-14 11:08:23">
This is entirely possible, using the exact syntax I used - you just need to be able to spell!

Resources