Latitude/Longitude not woking in EXIFR gem for Ruby - ruby-on-rails

Am trying to use the exifr gem to read lat/long for an image upload.
In the model:
attr_accessible :image, :post_process_photo, :width, :height, :model, :datetime, :latitude, :longitude
belongs_to :user
has_attached_file :image, styles: { medium: "300x300#", thumb: "50x50#", large:"500x500#" }
after_post_process :post_process_photo
def post_process_photo
imgfile = EXIFR::JPEG.new(image.queued_for_write[:original].path)
return unless imgfile
self.width = imgfile.width
self.height = imgfile.height
self.model = imgfile.model
self.datetime = imgfile.date_time
self.latitude = imgfile.gps.latitude
self.longitude = imgfile.gps.longitude
end
In the view... the width/height stuff is working, but lat/long isn't:
<%= #pic.width %> #this works!
<%= #pic.height %> #this works!
<%= #pic.latitude %> #this doesn't!
<%= #pic.longitude %> #this doesn't!
...which is odd, because it's marked up exactly as instructed in the gem docs.
Have also added the appropriate migrations to the DB, which appear as should on the schema.
The view renders undefined methodlatitude'`
Any help much appreciated!

I think you want imgfile.gps_latitude and imgfile.gps_longitude - underscored instead of dots

Related

nested form fields using fields_for is giving error "hash is defined by Active Record... same name"

I'm fairly new to rails, so excuse my ignorance. But I currently have a controller which stores "Scan Results" for a theoretical virus scanner.
The Scan Model, has_many Detections, which is a record which holds a Sha256 hash and a type.
the code looks as follows
model/scan.rb
class Scan < ApplicationRecord
has_many :detections, class_name: "detection", foreign_key: "d_id", :dependent => :destroy
accepts_nested_attributes_for :detections
validates :hostname, presence: true, uniqueness: { case_sensitive: true }, length: {maximum: 50, minimum: 1}, if: :hostname_not_empty
def hostname_not_empty
if ( self.hostname != '' || self.hostname.nil? )
return true
end
return errors.add(:scansErr, "Hostname is empty")
end
end
model/detections
class Detection < ApplicationRecord
belongs_to :scan
validates :hash, presence: true, length: {maximum: 64, minimum:64}, format: { with: /\b[A-Fa-f0-9]{64}\b/ }
def new ()
end
def new_record
end
end
when I try creating a template for adding new scans to the db, I'm getting this error hash is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
I'm using the following template to try and render it all.
views/dashboard/form.html.haml
...
= form_for :scans, url: dashboard_scan_create_path(params.to_unsafe_h.slice(:hostname)), :html => {:class => 'flex w-full flex-col scan-form' } do |s|
%div.flex.w-full.relative
#{s.text_field :hostname, :class => 'input border border-gray-400 appearance-none rounded w-full px-3 py-3 pt-8 pb-2 my-2 focus focus:border-indigo-600 focus:outline-none active:outline-none active:border-indigo-600' }
#{s.label :hostname, :class => 'label absolute mb-0 -mt-2 pt-4 pl-3 leading-tighter text-gray-400 text-base mt-2 cursor-text'}
%div.detections.flex.w-full.my-2{ 'data-controller' => 'detection-form' }
%div.text-xl.font-bold Detections
%template{"data-target" => "detection-form.template"}
= s.fields_for :detections, Detection.new, child_index: "NEW_RECORD" do |d_form|
= render "detection_fields", form: d_form
...
views/dashboard/detections-fields.html.haml
= content_tag :div, class: "detection-fields" do
.input.detection-field-input.d-flex.justtify-content-between.mb-2
.col-11.pl-0
= form.fields_for(:detection) do |detection_form|
= detection_form.text_field :type
= detection_form.text_field :hash
.col-1
= link_to "delete", "#", data: { action: "nested-form#remove_association" }
= form.hidden_field :_destroy, as: :hidden
can anyone help me figure out what I am doing wrong.
The error is clear in that ActiveRecord::Core has defined a method hash and your model, Detection, has a conflicting attribute called hash.
The action here is to rename the hash attribute of your model to something that isn't already implemented/reserved.
As an example, if you change the model attribute (and the associated code that uses it) to be sha256 or sha it will avoid the conflict.

How to use rich_text_area with simple_form in Ruby on Rails 6?

At the moment simple_form does not support ruby on rails 6 action_text with the rich_text_area input field.
So at the moment my input field can look like this in posts/_form.html.haml:
= f.label :description
= f.rich_text_area :description
= f.error :description, class: 'text-danger'
How to make it work as = f.input :description and have a rich text area?
create a file in app/inputs/rich_text_area_input.rb:
class RichTextAreaInput < SimpleForm::Inputs::Base
def input_html_classes
super.push('trix-content')
end
def input(wrapper_options = nil)
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
#builder.rich_text_area(attribute_name, merged_input_options)
end
end
in application.scss:
//simple_form input for rich_text_area hight
trix-editor.form-control {
height: auto;
}
Now in posts/_form.html.haml you can just do:
= f.input :description, as: :rich_text_area
Althrough hopefully at some point simple_form must add it to master
Source 1: https://github.com/heartcombo/simple_form/issues/1638
Source 2: https://github.com/heartcombo/simple_form/pull/1646

paperclip resize not working for dynamic columns on attachment model

I have a two columns on my attachment model on which the user sets the dimension to which they want to resize the image.
However, the variables when the resize happens are nil, but set to actual values after the resize happens.
below is the code
has_attached_file :file, :styles => lambda { |a|
{ :logo => ["200x50>",:png],
:user_defined => ["#{a.instance.custom_width}x#{a.instance.custom_height}>",:png] }
}
the custom_width & custom_height are nil when conversion happens however the logo conversion works as expected.
I am using ruby 2.2.4p230 & Rails 4.2.4
below is the full mode code
class Attachment < ActiveRecord::Base
belongs_to :model_one
belongs_to :attachable, polymorphic: true
#has_attached_file :file, styles: { logo: ['200x50>',:png] }
has_attached_file :file, styles: lambda { |attachment| attachment.instance.styles }
def styles
Rails.logger.info self.inspect
Rails.logger.info self.attachable
styles = {}
m = "200x50>"
l = "#{self.custom_width}x#{self.custom_height}>"
styles[:logo] = [m, :png]
styles[:user_defined] = [l, :png]
styles
end
end
Can anyone please help and let me know if i am doing something wrong?

how do sizing image with paperclip gem

i want to use avatar through paperclip. in tutorial use gravatar
messages_helper.rb
def recipients_options(chosen_recipient = nil)
s = ''
User.all.each do |user|
s << "<option value='#{user.id}'
data-img-src='#{gravatar_image_url(user.email, size: 50)}'
#{'selected' if user == chosen_recipient}>
#{user.name}</option>"
end
s.html_safe
end
i change on this code and it working.
module MessagesHelper
def recipients_options(chosen_recipient = nil)
s = ''
User.all.each do |user|
s << "<option value='#{user.id}' data-img-src='#{user.avatar.url(:thumb)}'
#{'selected' if user == chosen_recipient}>#{user.username}</option>"
end
s.html_safe
end
end
new.html.erb
<div class="form-group">
<%= label_tag 'recipients', 'Choose recipients' %>
<%= select_tag 'recipients', recipients_options(#chosen_recipient), multiple: true, class: 'form-control chosen-it ' %>
</div>
user.rb
has_attached_file :avatar, :styles => { :medium => "150x150>", :thumb => "30x30#" }, default_url: "https://s3.amazonaws.com/myinstick/logo/instagram-icon.png"
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
But! if user dont have avatar, that use image paperclip default. and it does not scaling and It looks big. how to set the style or size.
it looks like this
in your model:
has_attached_file :avatar,
:styles => { thumb: "100x100#", medium: "300x300#", large: "900x500#"}
or whatever size you want it to be. The # is for cropping. It will select the center of the image and crop the specified height and width from there. You can also just use the default > if you don't want the cropping... and in your view:
<%= image_tag #user.avatar.url(:medium) %>
I solved the problem. Drop-down list uses
jquery.image-select.js
(function($) {
// Image template, this can be overridden from the constructor (options.template),
// must contains {src} placeholder. Ther eare two class names 'chose-image' or 'chose-image-small', modifiy in CSS
var fn_template = '<img class="{class_name} " src="{url}" />';
// Store the original 'chosen' method
var fn_chosen = $.fn.chosen;........
I can set class for all images, like this
var fn_template = '<img class="{class_name} image-circle-minisize" src="{url}" />';
and everything works

Validate image size in carrierwave uploader

All uploads should be at least 150x150 pixels. How to validate it with Carrierwave?
Why not to use MiniMagick? Modified DelPiero's answer:
validate :validate_minimum_image_size
def validate_minimum_image_size
image = MiniMagick::Image.open(picture.path)
unless image[:width] > 400 && image[:height] > 400
errors.add :image, "should be 400x400px minimum!"
end
end
I made a slightly more complete validator based on #skalee's answer
class ImageSizeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value.blank?
image = MiniMagick::Image.open(value.path)
checks = [
{ :option => :width,
:field => :width,
:function => :'==',
:message =>"Image width must be %d px."},
{ :option => :height,
:field => :height,
:function => :'==',
:message =>"Image height must be %d px."},
{ :option => :max_width,
:field => :width,
:function => :'<=',
:message =>"Image width must be at most %d px."},
{ :option => :max_height,
:field => :height,
:function => :'<=',
:message =>"Image height must be at most %d px."},
{ :option => :min_width,
:field => :width,
:function => :'>=',
:message =>"Image width must be at least %d px."},
{ :option => :min_height,
:field => :height,
:function => :'>=',
:message =>"Image height must be at least %d px."},
]
checks.each do |p|
if options.has_key?(p[:option]) and
!image[p[:field]].send(p[:function], options[p[:option]])
record.errors[attribute] << p[:message] % options[p[:option]]
end
end
end
end
end
Use it like validates :image, :image_size => {:min_width=>400, :min_height => 400}.
It surprised me just how difficult it was to search around for a clear-cut way to validate image width & height with CarrierWave. #Kir's solution above is right on, but I wanted to go a step further in explaining what he did, and the minor changes I made.
If you look at his gist https://gist.github.com/1239078, the answer lies in the before :cache callback he has in the Uploader class. The magic line is
model.avatar_upload_width, model.avatar_upload_height = `identify -format "%wx %h" #{new_file.path}`.split(/x/).map { |dim| dim.to_i }
in his case, avatar_upload_width & avatar_upload_height are attributes of his User model. I didn't want to have to store width&height in the database, so in my model I said:
attr_accessor :image_width, :image_height
Remember, you can use attr_accessor for attributes you want to have on hand when messing with a record, but just don't want to persist them to the db. So my magic line actually turned into
model.image_width, model.image_height = `identify -format "%wx %h" #{new_file.path}`.split(/x/).map { |dim| dim.to_i }
So now I have the width & height of my image stored in the model object. The last step is to write a custom validation for the dimensions, so in your model you need something like
validate :validate_minimum_image_size
And then below it define your custom validation method, same as in the gist
# custom validation for image width & height minimum dimensions
def validate_minimum_image_size
if self.image_width < 400 && self.image_height < 400
errors.add :image, "should be 400x400px minimum!"
end
end
I just made a custom validator that aims to be more Rails 4+ syntax friendly.
I took ideas from the others responses on this thread.
Here is the gist: https://gist.github.com/lou/2881f1aa183078687f1e
And you can use it like this:
validates :image, image_size: { width: { min: 1024 }, height: { in: 200..500 } }
In this particular case it should be:
validates :image, image_size: { width: 150, height: 150 }

Resources