Create Refile attachment from HTTpary on a Ruby model with mongo db - ruby-on-rails

Building a mobile app with Rails backend, I would like to import the facebook profile picture from facebook to my own system using rails. The profile image is located at some url, and the pictures in my backend are being saved using Refile.
The ProfilePicture model:
class ProfilePicture
include Mongoid::Document
extend Refile::Mongoid::Attachment
attachment :file, type: :image
belongs_to :user
field :created_at, type: String
field :updated_at, type: String
end
The User model:
class User
include Mongoid::Document
field :created_at, type: String
field :updated_at, type: String
has_one :profile_picture
end
The code to set the Picture, using HTTParty:
#user = User.find_by(id: 1)
#picture_data = HTTParty.get("https://graph.facebook.com/me/picture", query: {
access_token: access_token,
type: "large"
})
pic = ProfilePicture.new(file: #picture_data.body)
#user.update(profile_picture: pic)
The profile picture is GETed, as I can see the data in the HTTP result. The DB result of the "Update" action above would be a new ProfilePicture record in the mongodb, with a reference to the user data, so that's OK too. So the only problem is, that the attachment is not being saved.
How do I save the attachement?

The answer was that the image file being GETed from facebook was not a valid "image" type for the attachment. The change was to remove the type from the attachment property, like so:
class ProfilePicture
include Mongoid::Document
extend Refile::Mongoid::Attachment
attachment :file
belongs_to :user
field :created_at, type: String
field :updated_at, type: String
end

Related

Rails Mongoid : Query embedded document and access to Mongoid criteria

I have an application where users can create many travels, and they can invite their facebook friends. In the travel document, there is a field "participants" that is an embedded document, Participant model embedded in Travel model.
Here are my models :
class Travel
include Mongoid::Document
include Mongoid::Timestamps
# relations
belongs_to :user
# fields
field :title, type: String
field :description, type: String
field :begin_date, type: Date
field :end_date, type: Date
field :budget, type: Integer
field :go_back, type: Boolean
field :title_namespace, type: String
# friends
embeds_many :participants
accepts_nested_attributes_for :participants
end
class Participant
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
field :user_id, type: String
# relations
embedded_in :travel, :inverse_of => :participants
end
When I try to display travel where users have been invited, with this request :
#travel_participations = Travel.where('participants.user_id' => #user.id)
I don't have any result, even if I have this line in byebug :
#<Mongoid::Criteria
selector: {"participants.user_id"=>BSON::ObjectId('592c8da58511989ec850921e')}
options: {}
class: Travel
embedded: false>
So when I put this on my view :
<% unless #participations.nil? %>
<% #travel_participations.each do |travel_participation| %>
<p> <%= travel_participation.title %> </p>
<% end %>
<% end %>
I tried with .all, .first, .to_a, .as_json, no results ... Some one know where is the problem ?
You have this in your embedded model:
field :user_id, type: String
but your query is using a BSON::ObjectId:
Travel.where('participants.user_id' => #user.id)
as shown in the raw query:
selector: {"participants.user_id"=>BSON::ObjectId('592c8da58511989ec850921e')}
Your embedded document probably has a string field like:
"user_id": "592c8da58511989ec850921e"
rather than the ObjectId you're looking for:
"user_id": ObjectId("592c8da58511989ec850921e")
so you won't find what you're looking for due to the type mismatch.
Either fix the embedded field's type:
field :user_id, type: BSON::ObjectId
or query it as the string it is:
Travel.where('participants.user_id' => #user.id.to_s)
Changing the type will involve fix up whatever data you already have, changing the query is ugly in a different way.
Sometimes Mongoid will convert between strings and ObjectIds for you, sometimes it won't. When I used Mongoid I patched to_bson_id methods into BSON::ObjectId, String, Mongoid::Document, ... so that I could say things like:
Model.where(:some_id => some_id.to_bson_id)
and not have to constantly worry about what type some_id was. I also made sure that all ID fields were always specified as BSON::ObjectId.

MongoId Unique Value inside Array

I try to do something like a find_or_create_by on an Array field.
Here is my model:
class Contact
include Mongoid::Document
include Mongoid::Attributes::Dynamic
field :id, type: String
field :emails, type: Array
field :phones, type: Array
field :first_name, type: String
field :last_name, type: String
field :fullcontact, type: Hash
end
I will create those Contacts with an email.
Emails field is an Array, for exemple I want to add test#test.com. How can I do a find_or_create on the array emails. If I have a Contact with test#test.com I want to find it or create one with email inside emails.

rails app - mongoid does not insert a new field

I just started to create on app with rails-api and mongoDB (gem mongoid in rails).
I have created my model like this:
class User
include Mongoid::Document
include Mongoid::Timestamps
embeds_many :language
accepts_nested_attributes_for :language
field :name, type: String
field :lastname, type: String
field :mail, type: String
field :passwd, type: String
field :auth_token, type: String
end
And i want to add another field in my model.
So at the end of my model i add this:
field :slug, type: String
But when i insert a new document, mongoid doesn't detect the new field and return null.
I try to do rake:migration but is useless with mongodb and i can't find the issue. Could you help me?
Best regards
Most probably you did not add that new field into your strong params whitelist.
Look into your controller and find a line that looks like this:
params.require(:user).permit(:name, ...)
Add slug there like this:
params.require(:user).permit(:name, ..., :slug)

undefined method `bson_type' in mongoid add_to_set

not sure what I'm doing wrong when adding an object to set, I'm getting the error undefined method 'bson_type' for #<Favorite:0x007ffadd59ba48> at the following line
favorite = Favorite.new(
item_id: params[:item_id],
item_type: params[:item_type],
duid: params[:duid],
name: params[:name]
)
profile.add_to_set(favorites: favorite)
models
class Favorite
include Mongoid::Document
embedded_in :profile
field :item_id, type: String
field :item_type, type: String
field :name, type: String
field :duid, type: String
end
class Profile
include Mongoid::Document
field :profile_id, type: String
field :name, type: String
field :image, type: String
embeds_many :favorites
end
One way to solve this issue is to use:
favorite = Favorite.new(item_id: params[:item_id], ... yada yada)
favorite.profile = profile
favorite.save!
Another way to solve this issue is to use the following code -- which I personally prefer:
profile.favorites.create!( item_id: params[:item_id], ...yada yada )
Extra Info can be ignored
class Profile
...
embeds_many :favorites, cascade_callbacks: true
...
end
to allow the running of the callbacks found in the Favorite model

Nested attributes in mongodb confusion

I am using rails with database Mongodb.
I am using devise . Devise has model name user.The id of the user is in
:id => current_user.id
I want to make a model such that when data is save from the form the id of the current user will also save in the collection.
The model of my employee is
class Employee
include Mongoid::Document
field :first_name, type: String
field :middle_name, type: String
field :last_name, type: String
field :otherid, type: String
field :licennum, type: String
field :citizennum, type: String
field :licenexp, type: String
field :gender, type: String
field :state, type: String
field :marital_status, type: String
field :country, type: String
field :birthdate, type: String
field :nickname, type: String
field :description, type: String
validates_presence_of :first_name
{
}
end
what should i put inside curly bracket so that when data is saved from that model it saves the current user id also inside it?
The code you show only contains personal information fields like birth date and such. I suppose the simplest solution would be to place them inside the User class, and change them using built-in devise actions such as devise/registrations#edit, which applies the changes to current_user as default.
Alternatively, if you want to keep Employee as a separate class, you could try embedding Employee in User class, like this:
class User
include Mongoid::Document
embeds_one :employee
(...)
class Employee
include Mongoid::Document
embedded_in :user
In this case, you would set up the relation at controller level, e.g.:
class EmployeesController < ApplicationController
def create
current_user.create_employee(params[:employee])
end
After creation, you could access the user's ID from Employee class as user.id.

Resources