In a specific view, I am rendering an array of POROs created from a SQL query (this is for performance reasons, having ActiveRecord models here would be a major performance problem).
In that view, I need to display an image uploaded with paperclip, but can't find a way of getting Paperclip to return an image url without an ActiveRecord (attachment) instance. I can get the name of the image from the DB ("image.jpg") and the Model name ("User") as well.
I would need something like url("image.jpg", :user, :thumb).
I could hardcode paths, but I would prefer not to, and let paperclip handle this.
Is this possible?
Thanks,
Ricardo
I created a gist for that here
Basically your object needs to implement some ActiveModel modules to fullfil Paperclip requirements, because this library is strongly coupled to ActiveRecord.
Related
How can I append an image to a model object in rails? For example, if I had a post, how could I upload/append an image to the object so that I can call it in the view dynamically? I know that the association would be a has_one relationship... Ive looked around and just can't find anything on this topic. Thanks.
The most common solution for model attachments in Rails is the Paperclip gem. Try using it, or take a look at a corresponding Ruby Toolbox category.
I'm building an API wrapper that will query objects from a third-party API and build them into objects to be used in my Rails environment. To do that, I'm building a set of models that use ActiveRecord (for some of its functionality) but are not database backed. I would like to be able to make a call like this:
obj = MyModel.find(1)
And have the code be something like this:
def MyModel.find id
# check for object in cache
# check for object in db
# grab object from API
# return object
end
Am I going to do something horribly wrong if I override the default find method? Am I approaching this in totally the wrong way?
If you are not using a database, then you do not need ActiveRecord. The entire purpose of ActiveRecord is to give you a mapping to a relational database.
I think what you want is for a class to implement certain pieces of what ActiveRecord provides, and Rails 3 has made those pieces into classes that you can include into regular 'ol classes on an as-needed basis. Look at this article for more details: http://www.rubyinside.com/rails-3-0s-activemodel-how-to-give-ruby-classes-some-activerecord-magic-2937.html
For instance, if you only want validations on a class, you can use include ActiveModel::Validations and then you'll get all of the nice error handling and .valid? and validates presence: true kind of behavior you're used to.
I would also suggest the railscast by Ryan Bates: http://railscasts.com/episodes/219-active-model which goes into more detail.
I'm trying to use Models in my Rails application that retrieve information from an external API. What I would like to do is access my data models (which may consist of information resulting from multiple API calls) in a way similar to what an ActiveRecord model would provide (specifically associations, and the same style of chain-able query methods).
My initial instinct was to recreate the parts of ActiveRecord that I wanted and incorporate this API. Not wanting to 'reinvent the wheel' and seeing exactly how much work would be required to add more functionality have made me take a step back and reevaluate how to approach this.
I have found ways to use ActiveRecord without a table (see: Railscast #193 Tableless Model and the blog post here) and looked into ActiveRecord. Because ActiveModel only seems to include Validations I'm not sure that's very helpful in this situation. The workaround to using ActiveRecord without a table seems like the best option, but I suspect there's a cleaner way of doing this that I'm just not seeing.
Here is a gist containing some of the code written when I was trying to recreate the ActiveRecord functionality, borrowing heavily from the ActiveRecord source itself.
My question boils down to: I can get the functionality I want (chaining query methods, relations) by either implementing the workaround to ActiveRecord specified above or recreating the functionality myself, but are these really ideal solutions?
Remember that Rails is still just Ruby underneath.
You could represent the external API as instantiated classes within your application.
class Event
def self.find(id)
#...External http call to get some JSON...#
new(json_from_api)
end
def initialize(json)
#...set up your object here...#
end
def attendees
#...external http call to get some JSON and then assemble it
#...into an array of other objects
end
end
So you end up writing local abstractions to create ruby objects from api calls, you can probably also mix in ActiveModel, or Virtus into it, so you can use hash assignment of attributes, and validations for forms etc.
Take a look at an API abstraction I did for the TfL feed for the tube. service_disruption
I'm creating a model in Ruby on Rails that will act like a file system. You'll have assets (like files) that could either be folders or files themselves. How can I create a command for this?
Asset
id (unique auto-incrementing number)
name
is_directory (bool)
user_id (id of the owner)
parent_asset_id (id of parent directory, or null if under the root)
access_token (randomly generated token, used to send shareable links)
contents
I'm thinking something like:
rails generate model Asset
name:string
is_directory:boolean
user_id:integer
parent_asset_id:integer
access_token:string contents:??
Some questions I have:
What's the difference betweeen blob vs longblob vs mediumblob vs longtext vs etc, and which would I want to use? (The assets are essentially text... not sure what the max size will be yet)
Is the parent_asset_id a good naming convention, or is there something else that would make Rails give me some secret sauce, similar to why I picked the name user_id (to match the User model)?
Is there a way to declare a default random string value for the access_token? (The access token will be used for a shareable link to the asset)
Anything else I'm overlooking?
This is a detailed question, so I hope it serves as a case study for anyone looking to implement something like a file system in RoR.
Obviously if you really wanted to implement a file system you'd use an actual file system or Amazon S3... but if you want a light-weight file-like system in RoR, this seems like the best approach.
First off, I strongly recommend you consider an existing gem like Paperclip, which will handle a lot of these details for you.
Answers in order:
You would use the binary field type to store general data, but if you use Paperclip there are some specific fields you would need to use instead, which are explained in Paperclip's docs.
If by parent_asset_id you really mean the asset can 'belong' to many other models, then look into setting up a polymorphic relationship, with an id and type field. If instead you mean storing the path to the stored file, then Paperclip handles this for you. See #3 for details...
You can access a stored file on Paperclip by calling something as simple as asset.url in your view. If you wish to go manual and insert a random code, you can insert a callback into your Asset.rb model that does something like:
before_create :generate_key
def generate_key
self.key = ActiveSupport::SecureRandom.hex
end
S3 is not a complex system to set up on Rails, and it is far more flexible and scaleable than storing the files elsewhere - however, if you want to, then use the 'assets' path.
Here is the scenario, i would like the user to input all the data and all and use em to populate a result. I won't need to store them in a database since i will just be showing them a result page.
I did http://railscasts.com/episodes/219-active-model and made my model tableless.
But now i have a problem when i wanna receive image upload from the user. I would also like to display that picture in the result page, and since i will just be using it once, if possible i wouldnt wanna store it in the database as well.
I tried implementing paperclip with the tableless model (since i couldnt find any other solution) but it seems that the model has inherit ActiveRecord::Base for it to work...
Is this possible? Or is this other way i can implement this?
Thanks!
If you were to succeed with using Paperclip for this, how would you get rid of the uploaded image once you no longer needed it? Without a database or some other form of persistent storage, how would you know where the image had been stored?
I think that you have some conceptual issues here that you should rethink before you start hacking up tableless models that accept image uploads.
But, if for some reason you really want to do it this way, then I would suggest just uploading the image without the benefit of a gem like Paperclip, which is really intended to make it easier to associate files with ActiveRecord objects. Just google for how you upload a file in Ruby, it's not really all that difficult.
OK, so you want to receive an image, and then display it right back, and not store the image. Can do.
What about a Controller that receives a file using multipart, and then transmits the file back to the request?
Controller file:
def upload
# Save file
name = params['datafile'].original_filename
directory = "tmp/uploads"
temp_file_name = File.join(directory, name)
send_file temp_file_name, :status=>200
end
You'll then just cleanup tmp when you need. Or, try out doing a File.delete temp_file_name when you need to.
If you want to validate that it's an image, you can do Paperclip model validation.