Rails paperclip unique image - ruby-on-rails

Hi im looking forward to fix this unique image name issue: when a user upload an image (every user have it own folder), and the image exists already,, im getting thie message.
Errno::EACCES in PlayerStepsController#update
Permission denied - /srv/www/myfootballproject.com/mfp/public/assets/people/14/original/chepo.jpg
Rails.root: /srv/www/myfootballproject.com/mfp
Application Trace | Framework Trace | Full Trace
app/controllers/player_steps_controller.rb:30:in `update'
Request
I look into stackoverflow, and first i read about setting the userid for folders this minimize the probs of same name, also i try to randomize, but this is not working at all, i get no errors neither a randomize name for image..
here is the part of the model doing this.
has_attached_file :avatar, :styles => { :profile => "300x300", :thumb => "100x100#"},
:url => "/assets/people/:id/:style/:basename.:extension",
:path => ":rails_root/public/assets/people/:id/:style/:basename.:extension"
before_create :randomize_file_name
private
def randomize_file_name
extension = File.extname(image_file_name).downcase
self.image.instance_write(:file_name, "#{ActiveSupport::SecureRandom.hex(16)}#{extension}")
end
here is the model (complete)
class Player < ActiveRecord::Base
belongs_to :user
has_many :clubs
has_many :links
has_many :references
has_many :achievements
has_many :citizens
has_and_belongs_to_many :languages
has_and_belongs_to_many :selections
accepts_nested_attributes_for :clubs, :allow_destroy => true, :reject_if => proc { |attributes| attributes['name'].blank? }
accepts_nested_attributes_for :links, :allow_destroy => true, :reject_if => proc { |attributes| attributes['url'].blank? }
accepts_nested_attributes_for :references, :allow_destroy => true, :reject_if => proc { |attributes| attributes['name'].blank? }
accepts_nested_attributes_for :achievements, :allow_destroy => true, :reject_if => proc { |attributes| attributes['name'].blank? }
accepts_nested_attributes_for :citizens, :allow_destroy => true, :reject_if => proc { }
attr_accessible :name,
:lastname,
:birthday,
:height,
:height_measure,
:weight,
:weight_measure,
:inches,
:city,
:birthplace,
:other_languages,
:cp,
:phone,
:cellphone,
:web_page,
:game_status,
:club,
:actual_club,
:actual_country_club,
:actual_division_club,
:actual_contract_expiration_club,
:last_club,
:last_country_club,
:last_division_club,
:last_contract_expiration_club,
:position,
:alternative_position,
:dominant_leg,
#normal player
:short_passes,
:long_passes,
:shots_half_distance,
:shots_long_distance,
:ball_habilities,
:offensive_capability,
:ball_driving,
:defense_capability,
:dribbling,
:velocity,
:vision_field,
:movements_wothout_ball,
:recovery_ball,
:head_ball,
:lidership,
:teamwork,
#goalkeeper
:air_game,
:clearance_technique, #técnica de despeje
:ball_keep, #atajes
:flexibility, #flexibilidad
:penalty_keep, #atajar penales
:achique,
:defense_communication,
:foot_game,
:velocity_reaction, #reflejos
:area_domination,
:goalkeep_teamwork,
:goalkeep_lidership,
:strenghts,
:weaknesses,
:aditional_information,
:active,
:clubs_attributes,
:links_attributes,
:references_attributes,
:achievements_attributes,
:citizens_attributes,
:avatar_file_name,
:avatar_content_type,
:avatar_file_size,
:avatar,
:language_ids,
:selection_ids
POSITIONS = %w{
goalkeeper
defense
medium
offensive
}
LEG = %w{
left
right
both
}
# altura
HEIGHT = (1..200).to_a
INCH = (1..11).to_a
# peso
WEIGHT = (1..300).to_a
HEIGHT_MEASURE = %w{
cms
pies
}
WEIGHT_MEASURE = %w{
kgs
lbs
}
has_attached_file :avatar, :styles => { :profile => "300x300", :thumb => "100x100#"},
:url => "/assets/people/:id/:style/:basename.:extension",
:path => ":rails_root/public/assets/people/:id/:style/:basename.:extension"
before_create :randomize_file_name
private
def randomize_file_name
extension = File.extname(image_file_name).downcase
self.image.instance_write(:file_name, "#{ActiveSupport::SecureRandom.hex(16)}#{extension}")
end
validates_attachment_size :avatar, :less_than => 2.megabytes # Solo aceptar imágenes menores a 2 Mb.
validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png', 'image/gif']
def defeated?
t = Time.now - created_at
mm, ss = t.divmod(60)
hh, mm = mm.divmod(60)
dd, hh = hh.divmod(24)
dd > 180 ? true : false
end
end
Everything is working perfect, i can upload images (As long as they do not exist in server)
Thanks

Related

Can't join 'ServiceTemplate' to association named 'miq_user_roles'; perhaps you misspelled it?

Why can't I join miq_user_roles with ServiceTemplate? ServiceTemplate has a column miq_group_id which is the id of miq_user_roles.
scope :public_service_templates, -> { joins(:miq_user_roles).where(miq_user_roles: { settings: nil }) }
When I try the above code I get the following error:
Can't join 'ServiceTemplate' to association named 'miq_user_roles'; perhaps you misspelled it?
Following is the actual model definition where I want to include miq_user_roles table.
class ServiceTemplate < ApplicationRecord
include SupportsFeatureMixin
DEFAULT_PROCESS_DELAY_BETWEEN_GROUPS = 120
GENERIC_ITEM_SUBTYPES = {
"custom" => N_("Custom"),
"vm" => N_("Virtual Machine"),
"playbook" => N_("Playbook"),
"hosted_database" => N_("Hosted Database"),
"load_balancer" => N_("Load Balancer"),
"storage" => N_("Storage")
}.freeze
SERVICE_TYPE_ATOMIC = 'atomic'.freeze
SERVICE_TYPE_COMPOSITE = 'composite'.freeze
RESOURCE_ACTION_UPDATE_ATTRS = [:dialog,
:dialog_id,
:fqname,
:configuration_template,
:configuration_template_id,
:configuration_template_type].freeze
include CustomActionsMixin
include ServiceMixin
include OwnershipMixin
include NewWithTypeStiMixin
include TenancyMixin
include ArchivedMixin
include CiFeatureMixin
include_concern 'Filter'
include_concern 'Copy'
validates :name, :presence => true
belongs_to :tenant
has_many :service_templates, :through => :service_resources, :source => :resource, :source_type => 'ServiceTemplate'
has_many :services
has_many :service_template_tenants, :dependent => :destroy
has_many :additional_tenants, :through => :service_template_tenants, :source => :tenant, :dependent => :destroy
has_one :picture, :dependent => :destroy, :as => :resource, :autosave => true
belongs_to :service_template_catalog
belongs_to :zone
belongs_to :currency, :inverse_of => false
has_many :dialogs, -> { distinct }, :through => :resource_actions
has_many :miq_schedules, :as => :resource, :dependent => :destroy
has_many :miq_requests, :as => :source, :dependent => :nullify
has_many :active_requests, -> { where(:request_state => MiqRequest::ACTIVE_STATES) }, :as => :source, :class_name => "MiqRequest"
virtual_column :type_display, :type => :string
virtual_column :template_valid, :type => :boolean
virtual_column :template_valid_error_message, :type => :string
virtual_column :archived, :type => :boolean
virtual_column :active, :type => :boolean
default_value_for :internal, false
default_value_for :service_type, SERVICE_TYPE_ATOMIC
default_value_for(:generic_subtype) { |st| 'custom' if st.prov_type == 'generic' }
virtual_has_one :config_info, :class_name => "Hash"
scope :with_service_template_catalog_id, ->(cat_id) { where(:service_template_catalog_id => cat_id) }
scope :without_service_template_catalog_id, -> { where(:service_template_catalog_id => nil) }
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }
scope :public_service_templates, -> { joins(:miq_user_roles).where(miq_user_roles: { settings: nil }) }
supports :order do
unsupported_reason_add(:order, 'Service template does not belong to a service catalog') unless service_template_catalog
unsupported_reason_add(:order, 'Service template is not configured to be displayed') unless display
end
alias orderable? supports_order?
alias validate_order supports_order?
def self.with_tenant(tenant_id)
tenant = Tenant.find(tenant_id)
where(:tenant_id => tenant.ancestor_ids + [tenant_id])\
end

Ruby - Query another table in a model definition

I want to query another table in a model definition. For instance, I have a table called miq_user_roles and I want to query and retrievesettings column value.
I tried adding the following
has_many :miq_user_roles
but when I try the where condition where(:settings => nil)
I get the error service_template doesn't have settings column. How can I query miq_user_roles for settings instead of service_template
service_template has a column called miq_group_id and its the id of miq_user_rolestable.
Following is the actual model definition where I want to include miq_user_roles table.
class ServiceTemplate < ApplicationRecord
include SupportsFeatureMixin
DEFAULT_PROCESS_DELAY_BETWEEN_GROUPS = 120
GENERIC_ITEM_SUBTYPES = {
"custom" => N_("Custom"),
"vm" => N_("Virtual Machine"),
"playbook" => N_("Playbook"),
"hosted_database" => N_("Hosted Database"),
"load_balancer" => N_("Load Balancer"),
"storage" => N_("Storage")
}.freeze
SERVICE_TYPE_ATOMIC = 'atomic'.freeze
SERVICE_TYPE_COMPOSITE = 'composite'.freeze
RESOURCE_ACTION_UPDATE_ATTRS = [:dialog,
:dialog_id,
:fqname,
:configuration_template,
:configuration_template_id,
:configuration_template_type].freeze
include CustomActionsMixin
include ServiceMixin
include OwnershipMixin
include NewWithTypeStiMixin
include TenancyMixin
include ArchivedMixin
include CiFeatureMixin
include_concern 'Filter'
include_concern 'Copy'
validates :name, :presence => true
belongs_to :tenant
has_many :service_templates, :through => :service_resources, :source => :resource, :source_type => 'ServiceTemplate'
has_many :services
has_many :service_template_tenants, :dependent => :destroy
has_many :additional_tenants, :through => :service_template_tenants, :source => :tenant, :dependent => :destroy
has_one :picture, :dependent => :destroy, :as => :resource, :autosave => true
belongs_to :service_template_catalog
belongs_to :zone
belongs_to :currency, :inverse_of => false
has_many :dialogs, -> { distinct }, :through => :resource_actions
has_many :miq_schedules, :as => :resource, :dependent => :destroy
has_many :miq_requests, :as => :source, :dependent => :nullify
has_many :active_requests, -> { where(:request_state => MiqRequest::ACTIVE_STATES) }, :as => :source, :class_name => "MiqRequest"
virtual_column :type_display, :type => :string
virtual_column :template_valid, :type => :boolean
virtual_column :template_valid_error_message, :type => :string
virtual_column :archived, :type => :boolean
virtual_column :active, :type => :boolean
default_value_for :internal, false
default_value_for :service_type, SERVICE_TYPE_ATOMIC
default_value_for(:generic_subtype) { |st| 'custom' if st.prov_type == 'generic' }
virtual_has_one :config_info, :class_name => "Hash"
scope :with_service_template_catalog_id, ->(cat_id) { where(:service_template_catalog_id => cat_id) }
scope :without_service_template_catalog_id, -> { where(:service_template_catalog_id => nil) }
scope :with_existent_service_template_catalog_id, -> { where.not(:service_template_catalog_id => nil) }
scope :displayed, -> { where(:display => true) }
scope :public_service_templates, -> { where(:display => true) }
supports :order do
unsupported_reason_add(:order, 'Service template does not belong to a service catalog') unless service_template_catalog
unsupported_reason_add(:order, 'Service template is not configured to be displayed') unless display
end
alias orderable? supports_order?
alias validate_order supports_order?
def self.with_tenant(tenant_id)
tenant = Tenant.find(tenant_id)
where(:tenant_id => tenant.ancestor_ids + [tenant_id])\
end
Add the table name:
where("miq_user_roles.settings" => nil)
Arel is nice, but you still have to use bits of SQL to get over issues like this.
You will have to use joins, to query on the associated table.
ServiceTemplate.joins(:miq_user_roles).where(miq_user_roles: { settings: nil })

Rails Nested forms, not add a second element if user dont clic on "add new"

Hi im using Rails Nested forms, i need something very simple, but i cant figure put why, cause im a noob in Rails.
In the nested forms, when the user select an option on the list, the script automatically insert a second select list, in blank, this blanks remains always there,
Is there a way to avoid this.. so if you select nothing happends, (just the selection ofcourse) until you hit "add new", just then the script add a new select list for user to add another option.
Thanks..
View code
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
Model Player.rb
class Player < ActiveRecord::Base
belongs_to :user
has_many :clubs
has_many :links
has_many :references
has_many :achievements
has_many :citizens
has_and_belongs_to_many :languages
has_and_belongs_to_many :selections
accepts_nested_attributes_for :clubs, :allow_destroy => true, :reject_if => proc { |attributes| attributes['name'].blank? }
accepts_nested_attributes_for :links, :allow_destroy => true, :reject_if => proc { |attributes| attributes['url'].blank? }
accepts_nested_attributes_for :references, :allow_destroy => true, :reject_if => proc { |attributes| attributes['name'].blank? }
accepts_nested_attributes_for :achievements, :allow_destroy => true, :reject_if => proc { |attributes| attributes['name'].blank? }
accepts_nested_attributes_for :citizens, :allow_destroy => true, :reject_if => proc { |attributes| attributes['country_id'].blank?}
attr_accessible :name,
:lastname,
:birthday,
:height,
:height_measure,
:weight,
:weight_measure,
:inches,
:city,
:birthplace,
:other_languages,
:cp,
:phone,
:cellphone,
:web_page,
:game_status,
:club,
:actual_club,
:actual_country_club,
:actual_division_club,
:actual_contract_expiration_club,
:last_club,
:last_country_club,
:last_division_club,
:last_contract_expiration_club,
:position,
:alternative_position,
:dominant_leg,
#normal player
:short_passes,
:long_passes,
:shots_half_distance,
:shots_long_distance,
:ball_habilities,
:offensive_capability,
:ball_driving,
:defense_capability,
:dribbling,
:velocity,
:vision_field,
:movements_wothout_ball,
:recovery_ball,
:head_ball,
:lidership,
:teamwork,
#goalkeeper
:air_game,
:clearance_technique, #técnica de despeje
:ball_keep, #atajes
:flexibility, #flexibilidad
:penalty_keep, #atajar penales
:achique,
:defense_communication,
:foot_game,
:velocity_reaction, #reflejos
:area_domination,
:goalkeep_teamwork,
:goalkeep_lidership,
:strenghts,
:weaknesses,
:aditional_information,
:active,
:clubs_attributes,
:links_attributes,
:references_attributes,
:achievements_attributes,
:citizens_attributes,
:avatar_file_name,
:avatar_content_type,
:avatar_file_size,
:avatar,
:language_ids,
:selection_ids
POSITIONS = %w{
goalkeeper
defense
medium
offensive
}
LEG = %w{
left
right
both
}
# altura
HEIGHT = (1..200).to_a
INCH = (1..11).to_a
# peso
WEIGHT = (1..300).to_a
HEIGHT_MEASURE = %w{
cms
pies
}
WEIGHT_MEASURE = %w{
kgs
lbs
}
Paperclip.interpolates :random_hex do |attachment, style|
attachment.instance.random_hex
end
has_attached_file :avatar, :styles => { :profile => "300x300", :thumb => "100x100#"},
:url => "/assets/people/:id/:style/:hash.:extension",
:path => ":rails_root/public/assets/people/:id/:style/:hash.:extension",
:hash_secret => "longSecretString"
validates_attachment_size :avatar, :less_than => 2.megabytes # Solo aceptar imágenes menores a 2 Mb.
validates_attachment_content_type :avatar, :content_type => ['image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png', 'image/gif']
def defeated?
t = Time.now - created_at
mm, ss = t.divmod(60)
hh, mm = mm.divmod(60)
dd, hh = hh.divmod(24)
dd > 180 ? true : false
end
end
Model citizen.rb
class Citizen < ActiveRecord::Base
attr_accessible :country_id
belongs_to :player
end

How to display images in the list action of rails_admin?

I have a self-associating model which allows the user to define a "parent photo", in order to group them together.
My model:
class Photo < ActiveRecord::Base
attr_accessible :image, :parent_photo
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }
validates_attachment :image,
:presence => true,
:size => { :in => 20..2000.kilobytes },
:content_type => { :content_type => [ 'image/jpeg', 'image/png' ] }
belongs_to :parent, class_name: "Photo", foreign_key: :parent_photo
def associated_photos
Photo.find_by_parent_photo(id)
end
end
And in my rails_admin initializer:
..
config.model Photo do
list do
field :image
field :associated_photos
end
end
end
How do I retrieve the actual thumbnail for use in the list action?
It seems like this is addressed on the wiki under the heading "Fields - Output formatting."
Will something like this work?
config.model Photo do
list do
field :image do
formatted_value do
bindings[:view].tag(:img, { :src => bindings[:object].image.url }) << value
end
field :associated_photos
end
end
To show the image field:
config.model Photo do
list do
field :image do
pretty_value do
bindings[:view].tag(:img, { :src => bindings[:object].image.url(:thumb) })
end
end
end
end

rails 3 custom validation error messages in a join table, how?

How can I return errors messages from a cross reference table with multiple records when I trying to create those? I'm trying this:
## activity_set.rb
class ActivitySet < ActiveRecord::Base
has_many :activity_set_lessons
has_many :lessons, :through => :activity_set_lessons
validates :name, :presence => true
def activity_set_lessons=(data)
data.each_with_index do |v, i|
activity_set_lessons.build(
:lesson_id => v[:lesson_id],
:sort_order => i,
:weight_percentage => v[:weight_percentage]
)
end
end
end
## activity_set_lesson.rb
class ActivitySetLesson < ActiveRecord::Base
belongs_to :activity_set
belongs_to :lesson
validates :lesson_id, :presence => true
validates_each :weight_percentage do |record, attr, value|
record.errors.add :base, "woot" if value.blank?
end
end
This is the request data:
## params[:activity_set]
"activity_set" => {
"name" => "hshshshs",
"keywords" => "",
"activity_set_lessons" => [
{"weight_percentage" => "", "lesson_id"=>"4"},
{"weight_percentage" => "", "lesson_id"=>"5"}
]
}
Error messages from #activity_set when I do #save:
{
"errors":{
"activity_set_lessons":["is invalid","is invalid"]
},
"full_messages":[
"Activity set lessons is invalid","Activity set lessons is invalid"
]
}
I always got the same error message even if I'm adding a custom one in the join table. How can I return a message like: "woot 1 is wrong" or something like that, per validation?.
Thanks.
make use of accepts_nested_attributes_for
## activity_set.rb
class ActivitySet < ActiveRecord::Base
has_many :activity_set_lessons
has_many :lessons, :through => :activity_set_lessons
validates :name, :presence => true
accepts_nested_attributes_for :activity_set_lessons
end
view will look like
= form_for #activity_set do |f|
[activity_set form fields ]
= f.fields_for :activity_set_lessons do |p|
= p.select :lession_id
= p.select :weight_percentage

Resources