class Portfolio::PortfolioImage < PortfolioPost
has_attached_file :file,
styles: { _medium: ["960x", :jpg] },
default_style: :original,
preserve_files: true,
path: base_upload_url+ ":assign_user_id" + "_" + ":file_name" + ".jpg"
validates_attachment_content_type :file, content_type: /\Aimage/
before_post_process :downcase_file_name
def downcase_file_name
self.file_file_name = self.file_file_name.downcase
end
end
def index
#portfolio_image = PortfolioImage.all.paginate(:page => params[:page], :per_page => 20)
#portfolio_video = PortfolioVideo.all.paginate(:page => params[:page], :per_page => 20)
#portfolio_doc = PortfolioDocument.all.paginate(:page => params[:page], :per_page => 20)
render json: #portfolio_image
render json: #portfolio_video
render json: #portfolio_doc
end
How to solve this problem I have to create an api for index action where three types of data I have to see when chosen image only images should show and if chosen video only video should show.?
I'm not sure, but I think what you're missing is the Module prefix.
For ex. to get all portfolio images you want to use Portfolio::PortfolioImage.all. (Except when you're calling from inside the module, but that's not very clear from your question)
Related
This is what I have:
def index
#attachments = current_user.attachments.all
respond_to do |format|
format.json do
render :json => #attachments.map { |o| { url: o.picture.thumb.url }}
end
end
end
=> [{:url=>"/uploads/attachment/picture/7/thumb_df3c0c3c.jpg"}, {:url=>"/uploads/attachment/picture/12/thumb_dd7839ee.jpg"}, ... }]
How can I change the key from :url to :thumb?
=> [{:thumb=>"/uploads/attachment/picture/7/thumb_df3c0c3c.jpg"},
{:thumb=>"/uploads/attachment/picture/12/thumb_dd7839ee.jpg"}, ... }]
This is the whole object after: render :json => #attachments
My goal: thumb: thumb: "/uploads/attach..."
Background: https://www.froala.com/wysiwyg-editor/docs/concepts/image-manager
I use the gem carrierwave to create a thumb
response.map! { |urls| { :thumb => urls[:url] } }
change key from "url" to "thumb"
render :json => #attachments.map { |o| { **thumb: o.picture.thumb.url** }}
I am trying to implement the steps to check and resize images with paperclip based on this blog post: http://www.techdarkside.com/how-to-re-size-images-that-are-too-large-on-the-fly-with-paperclip-and-rails
Here is what I have in place...
class Question < ActiveRecord::Base
# subclasses
class Question::Image < Asset
has_attached_file :attachment,
:url => "/uploads/:class/:attachment/:id_partition/:basename_:style.:extension",
:styles => Proc.new { |attachment| attachment.instance.styles },
:styles => Proc.new { |attachment| attachment.instance.resize }
attr_accessible :attachment
# http://www.ryanalynporter.com/2012/06/07/resizing-thumbnails-on-demand-with-paperclip-and-rails/
def dynamic_style_format_symbol
URI.escape(#dynamic_style_format).to_sym
end
def styles
unless #dynamic_style_format.blank?
{ dynamic_style_format_symbol => #dynamic_style_format }
else
{ :medium => "300x300>", :thumb => "100x100>" }
end
end
def dynamic_attachment_url(format)
#dynamic_style_format = format
attachment.reprocess!(dynamic_style_format_symbol) unless attachment.exists?(dynamic_style_format_symbol)
attachment.url(dynamic_style_format_symbol)
end
def resize
if self.attachment_file_size > 2000000
"300x300>"
else
" "
end
end
end
I'm thinking the issue is with the reuse of the :styles symbol, however I'm not sure how to work both the styles method AND the resize method into a single Proc statement.
Here is what I ended up with thanks to #janfoeh suggestion. I did need to add :originalto the options in style to get this to work. I also bumped the max file size up to 5mb.
class Question < ActiveRecord::Base
# subclasses
class Question::Image < Asset
has_attached_file :attachment,
:url => "/uploads/:class/:attachment/:id_partition/:basename_:style.:extension",
:styles => Proc.new { |attachment| attachment.instance.styles }
attr_accessible :attachment
# http://www.ryanalynporter.com/2012/06/07/resizing-thumbnails-on-demand-with-paperclip-and-rails/
def dynamic_style_format_symbol
URI.escape(#dynamic_style_format).to_sym
end
def styles
unless #dynamic_style_format.blank?
{ dynamic_style_format_symbol => #dynamic_style_format }
else
{ :original => resize, :medium => "300x300>", :thumb => "100x100>" }
end
end
def dynamic_attachment_url(format)
#dynamic_style_format = format
attachment.reprocess!(dynamic_style_format_symbol) unless attachment.exists?(dynamic_style_format_symbol)
attachment.url(dynamic_style_format_symbol)
end
def resize
if self.attachment_file_size > 5000000
"1000x1000>"
else
" "
end
end
end
Is there a best practice for managing objects between model and controller in Rails? I've got code that clumsily hands files from controller to model and back like so:
In document_controller.rb:
tmp_file = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
pdf = Prawn::Document.generate(tmp_file.path(), :page_size => "A4", :skip_page_creation => true) do |posting|
#document.process(posting)
send_data posting.render, :filename => "#{#document.id}", :type => "application/pdf"
end
And in document.rb:
def process(pdf)
pdf.start_new_page
pdf.image self.user.logo.path, :width => pdf.bounds.width
pdf.fill_color '#444444'
pdf.image self.component.image_snapshot.path, :width => pdf.bounds.width
pdf.move_down 20
pdf.indent 20 do
pdf.text self.component.name, :size => 24
end
box_start = pdf.cursor
pdf.reflow_column_box([20, box_start-15], :width => pdf.bounds.width-20) do
format_for_prawn(pdf, self.component.body, self.user.colour1)
end
end
How can I rewrite this code so I don't have to clumsily pass the pdf/posting object around? It feels very un-Rails-like.
Thanks for your input.
EDIT: worse example.
Again in the controller:
tempfile = Magick::Image.read(#document.component.image_newsletter.path).first
overlay = Magick::Image.read(#document.user.logo.path).first.resize_to_fit(tempfile.columns)
rec = Magick::Draw.new
rec.stroke = "##{#document.user.colour1}"
rec.fill = "##{#document.user.colour1}"
rec.rectangle 0, 0, tempfile.columns, 5
lank = tempfile.extent(tempfile.columns, tempfile.rows+overlay.rows, 0 ,0)
final = lank.composite(overlay, Magick::SouthGravity, 0, 0, Magick::OverCompositeOp)
rec.draw(final)
send_data final.to_blob, :filename => "#{#document.user.name}-#{#document.id}.jpg", :type => "image/jpg"
This is in the controller because otherwise send_data can't access final. Any help?
Thanks again.
EDIT
You can create extension methods for inbuilt Class by
#lib/ext/prawn/document.rb
class Prawn::Document
def process(pdf)
pdf = self if pdf.blank?
pdf.start_new_page
pdf.image self.user.logo.path, :width => pdf.bounds.width
pdf.fill_color '#444444'
pdf.image self.component.image_snapshot.path, :width => pdf.bounds.width
pdf.move_down 20
pdf.indent 20 do
pdf.text self.component.name, :size => 24
end
box_start = pdf.cursor
pdf.reflow_column_box([20, box_start-15], :width => pdf.bounds.width-20) do
format_for_prawn(pdf, self.component.body, self.user.colour1)
end
end
end
And in your controller
tmp_file = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
pdf = Prawn::Document.generate(tmp_file.path(), :page_size => "A4", :skip_page_creation => true) do |posting|
posting.process
send_data posting.render, :filename => "#{#document.id}", :type => "application/pdf"
end
To load this class, you will need to require it in your config/application.rb file or in an initializer.
require 'ext/prawn/document'
To get that messy controller code into the model I've done this:
def process_media
temp = "#{::Rails.root}/public/temporary/#{temp_file_name}"
tempfile = Magick::Image.read(self.component.image_newsletter.path).first
overlay = Magick::Image.read(self.user.logo.path).first.resize_to_fit(tempfile.columns)
rec = Magick::Draw.new
rec.stroke = "##{self.user.colour1}"
rec.fill = "##{self.user.colour1}"
rec.rectangle 0, 0, tempfile.columns, 5
lank = tempfile.extent(tempfile.columns, tempfile.rows+overlay.rows, 0 ,0)
final = lank.composite(overlay, Magick::SouthGravity, 0, 0, Magick::OverCompositeOp)
rec.draw(final)
final.to_blob
final.write("#{temp}.jpg")
end
And I'm sending the actual file with send_file from the controller. Hope that helps someone.
I have a method that return a Hash and then I write the entries of hash in xml file. Iwant to convert this Hash to an object to store the entry and then write it to xml file...
My current code is like this
def entry(city)
{
:loc => ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => #country_host.value),
:changefreq => 0.8,
:priority => 'monthly',
:lastmod => city.updated_at
}
end
The write_entry method is inside my writer class that writes this entry to xml file
def write_entry(entry)
url = Nokogiri::XML::Node.new( "url" , #xml_document )
%w{loc changefreq priority lastmod}.each do |node|
url << Nokogiri::XML::Node.new( node, #xml_document ).tap do |n|
n.content = entry[ node.to_sym ]
end
end
url.to_xml
end
Thanks
I might be way off here, but it seems like what you're trying to do is something like this:
First, figure out what makes sense as a class name for your new object. I'm going with Entry, because that's the name of your method:
class Entry
end
Then take all the "properties" of your hash and make them reader methods on the object:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :lastmod
end
Next you need to decide how this object will be initialized. It seems like you will need both the city and #country_host for this:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :last mod
def initialize(city, country_host_value)
#loc = ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => country_host_value)
#changefreq = 0.8 # might actually want to just make this a constant
#priority = 'monthly' # another constant here???
#lastmod = city.updated_at
end
end
Finally add your XML builder method to the class:
class Entry
attr_reader :loc, :action, :changefreq, :priority, :last mod
def initialize(city, country_host_value)
#loc = ActionController::Integration::Session.new.url_for(:controller => 'cities', :action => 'show', :city_name => city.name, :host => country_host_value)
#changefreq = 0.8 # might actually want to just make this a constant
#priority = 'monthly' # another constant here???
#lastmod = city.updated_at
end
def write_entry_to_xml(xml_document)
url = Nokogiri::XML::Node.new( "url" , xml_document )
%w{loc changefreq priority lastmod}.each do |node|
url << Nokogiri::XML::Node.new( node, xml_document ).tap do |n|
n.content = send(node)
end
end
url.to_xml
end
end
Now that your hash has been refactored, you can update your other class(es) to use the new object:
class WhateverClassThisIs
def entry(city)
Entry.new(city, #country_host.value)
end
end
It's not clear how the XML writer method is being called, but you would need to update that as well to use the new write_entry_to_xml method, passing in the xml document as an argument.
I know how to access foreign key attributes in a scaffold index view. I can simply refer to the attributes using dot notation such as property.que.name. Given the following models:
class Priority < ActiveRecord::Base
belongs_to :que
...
end
class Que < ActiveRecord::Base
has_many :priorities
...
end
In the index view, I can do something like this to get the name value:
<td><%=h priority.que ? priority.que.name : "" %></td>
How do I do this in the jqgrid?
I tried this but the jqgrid comes back empty:
Priorities Controller:
#priorities = Priority.find(:all, :order => "position", :conditions => "multitenant_team_id = " + current_user.team.id.to_s ) do
if params[:_search] == "true"
id =~ "%#{params[:id]}%" if params[:id].present?
issue_id =~ "%#{params[:issue_id]}%" if params[:issue_id].present?
que =~ "%#{params[:que]}%" if params[:que].present?
customer =~ "%#{params[:customer]}%" if params[:customer].present?
title =~ "%#{params[:title]}%" if params[:title].present?
reporting_source =~ "%#{params[:reporting_source]}%" if params[:reporting_source].present?
priority =~ "%#{params[:priority]}%" if params[:priority].present?
product =~ "%#{params[:product]}%" if params[:product].present?
current_owner =~ "%#{params[:current_owner]}%" if params[:current_owner].present?
end
paginate :page => params[:page], :per_page => params[:rows]
order_by "#{params[:sidx]} #{params[:sord]}"
end
if request.xhr?
end
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #priorities.to_jqgrid_json(
[:id, :issue_id, :que.name, :customer, :title, :reporting_source,
:priority, :product, :current_owner],
params[:page], params[:rows], #priorities.total_entries)}
format.xml { render :xml => #priorities }
end
end
Index View:
<%= jqgrid("Priorities", "priorities", "/priorities",
[
{:field => "id", :label => "ID", :width => 35, :resizable => false},
{:field => "issue_id", :label => "Issue Id"},
{:field => "que", :label => "Queue"},
{:field => "customer", :label => "Customer"},
{:field => "title", :label => "Title"},
{:field => "reporting_source", :label => "Reporting Source"},
{:field => "priority", :label => "Priority"},
{:field => "product", :label => "Product"},
{:field => "current_owner", :label => "Current Owner"}
],
{ :rows_per_page => 12, :height => 450 }
)%>
If I specify que instead of que.name, I get the data back in the grid but the Queue field shows a "#" symbol so I suspect the .to_jqgrid_json call doesn't like my syntax.
Has anyone tried this before? I hope so.
I fixed my problem. I ended up changing my find to a find_by_sql so I could do a left outer join on the ques table. I think there were a couple of issues. I think the *to_jqgrid_json* had problems with null foreign key values and I couldn't figure out how to get at the Que.name any other way. I'm using SQLServer so I had to use isnull(ques.name, '') to convert the null to empty space.
So I replaced my find as follows:
#priorities = Priority.find_by_sql ["select priorities.id id, issue_id, isnull(ques.name,' ') queue_name, customer, title, reporting_source, priority, product, current_owner from priorities left outer join ques on priorities.que_id = ques.id where priorities.multitenant_team_id = ? order by issue_id", current_user.team.id.to_s]
This introduced another problem in that find_by_sql returns an array which breaks the #priorities.total_entries call. So I had to replace it with array.count.
format.json { render :json => #priorities.to_jqgrid_json(
[:id, :issue_id, :queue_name, :customer, :title, :reporting_source, :priority, :product, :current_owner],
params[:page], params[:rows], #priorities.count)}
My grid looks great!
Edit
My grid LOOKS great but it doesn't paginate or sort. Back to the drawing board. :(
Okay, I think I fixed it for real this time.
#priorities = Priority.find(:all,
:select => "priorities.id, priorities.issue_id,
priorities.customer, priorities.title,
priorities.reporting_source, priorities.priority,
priorities.product, priorities.current_owner,
priorities.position,
isnull(ques.name,' ') queue_name",
:joins => "LEFT OUTER JOIN ques ON ques.id = priorities.que_id",
:order => "priorities.position",
:conditions => "priorities.multitenant_team_id = " + current_user.team.id.to_s ) do
I had know idea I could specify joins like this. This keeps the resultset in a format the 2dc_jqgrid plugin likes. Sorting, pagination and searching all work now. Now my grid looks good and actually works.