30
Jun
09

Mandando archivos a otra aplicacion de Rails

El problema: ActiveResource es muy bueno para hacer que dos aplicaciones
de Rails se comuniquen satisfactoriamente, sin embargo, una vez que se
habla de file uploads y de soporte para multipart, la cosa se complica
un poco, ya que ActiveResource no tien soporte para esto.

Contexto: Railsy-fu es una aplicacion que usa el plugin attachment-fu
para poder hacer file uploads. (Ver el post anterior). RailsyResource es
una aplicacion que usa los web services de de Railsy-fu. RailsyResource
es la que se va a encargar de hacer los file uploads.

En este ejemplo, una mensaje puede o no tener un attachment. Vamos a
tener que primero hacer el upload a Railsy-fu y después tomar el id de
ese file para relacionarlo con la aplicación.

Como no podemos usar ActiveResource, vamos a tener que hacer un post
desde RailsyResource a Railsy-fu con multipart. Para poder hacer esto,
existe la ‘gem httpclient’. (Instalarla… gem i httpclient).

El procedimiento es asi…

1) Instanciamos el objeto Httpclient
clnt = HTTPClient.new

2) El archivo que se va a ser uploaded, tiene un filename del tipo
RackMultipart0123456789 y se encuentra en /tmp/ comúnmente. Como es un
archivo temporal, no podemos renombrarlo ahi mismo en /tmp/ , entonces
debemos de copiar el archivo a una carpeta temporal dentro del
RAILS_ROOT
name = params[:message][:file].original_filename
directory = "#{RAILS_ROOT}/public/temp/"
path = File.join(directory, name)
File.open(path, "w+") { |f| f.write(params[:message][:file].read) }

3) Ya que ha sido creado el archivo con su nombre original, lo mandamos
por post/put a el web service de Railsy-fu.
body = { :uploaded_data => File.open("#{RAILS_ROOT}/public/temp/" + name), :message => ‘yeah!!!’, :apikey => ‘12312312312312312123123′}
res = clnt.post(’http://railsyfu.com/files.xml’, body)

4) Necesitaremos el file_id de ese archivo que acabamos de guardar para
poder relacionarlo con el objeto. Para hacer esto vamos a parsear el
response (con libxml-ruby, es más rápido según esto).
doc = XML::Document.string(res.content)
file_id = doc.root.find_first(’id’).content #por ejemplo <id> 145 </id>

5) Y se lo anhadimos al objeto message.
@message.file_id = file_id

Falta despues hacer revisar si es que se no se hizo un attachment, asi
que todo lo anterior deberia de estar dentro de un if que hace esta
verificacion.

Por ultimo, borramos el archivo temporal que hicimos.
if @message.save
File.delete("#{RAILS_ROOT}/public/temp/" + name) if params[:message][:file] and File.exists?("#{RAILS_ROOT}/public/temp/" + name)

24
Jun
09

Testing Attachment fu

Quick post de como hacer el testing a attachment fu:

1.- Hacemos una carpeta dentro de fixtures que se llame files:
mkdir test/fixtures/files

2.- …incluimos algun archivo doc, imagen lo que sea.

3.- Dentro del test hacemos el load de esta forma

test &quot;should create person&quot; do
fdata = fixture_file_upload(’/files/doctestfile.doc’, ‘application/msword’)
assert_difference(’Person.count’) do
post :create, :resume =&gt; {
:person_id =&gt; 1,
:uploaded_document =&gt; fdata
},:html =&gt; { :multipart =&gt; true }
end
end

y ya… creo que ya

23
Jun
09

Usando attachment fu para para hacer uploads de documentos

Es muy parecido a lo de las imágenes.

Primero se instalamos el plugin…


ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu

Se genera el modelo del documento…


ruby script/generate model Document record_id:integer record_type:string filename:string content_type:string size:integer

rake db:migrate para las migraciones. Y ahora se anhade lo siguiente al model de ‘Document’. Las opciones completas de lo que se puede hacer están acá: http://wiki.github.com/technoweenie/attachment_fu.


class Document < ActiveRecord::Base
belongs_to :record, :polymorphic => true
has_attachment :content_type => ['application/pdf', 'application/msword', 'text/plain'],
:storage => :file_system,
:path_prefix => 'public/records'

validates_as_attachment
end

Los últimos pasos son agregar el metodo uploaded_document= a los modelos que se relacionan con los archivos. Por ejemplo: Person.rb tiene un documento.


class Person < ActiveRecord::Base

has_one :document, :dependent => :destroy, :as => :record

validates_presence_of :title
validates_length_of :title, :in => 1..100
validates_length_of :rating, :in => 0..10, :allow_nil => true

def uploaded_document=(data)
unless data.blank?;
document.destroy if document
self.reload
create_document :uploaded_document => data ##dudas en esta parte... :uploaded_data???
end
end

end

Para aceptar uploads en la vista se tiene que incluir esto en la forma.


<% form_for @movie, :html => {:multipart => true} do |f| %>

...

Document
<%= f.file_field :uploaded_document %>

ejemplo de liga al documento: <%= link_to “Document”, person.document.public_filename if person.document %>

Bueno ciao.

16
Jun
09

Shigoto notes #1

Para las migraciones…

rake db:create
rake db:migrate

me salio este error…

undefined method `reenable’ for <Rake::Task db:schema:dump =>
[environment]>:Rake::Task

eso significa que tengo que actualizar rake probablemente…

(estoy en ubuntu)

sudo aptitude remove rake
sudo gem install rake

06
Jun
09

Stack overflow topbar

<!– aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa –>
<div id="topbar">
<div id="hlinks">
<a href="/users/recent/9082"><img src="/content/img/so/replies-off.png" width="15" height="10" title="you have no new replies"></a>

<a href="/users/9082/wallyqs" rel="canonical">wallyqs</a>&nbsp;
<span class="reputation-score" title="reputation score">123</span>
<span title="7 bronze badges"><span class="badge3">●</span>
<span class="badgecount">7</span></span>
<span class="link-separator">|</span>
<a href="/users/logout?returnurl=%2f">logout</a>
<span class="link-separator">|</span>
<a href="/about">about</a> <span class="link-separator">|</span>
<a href="/faq">faq</a>
</div>
<!– aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa –>

29
May
09

Posteando desde la cajita

Posteando desde la cajita

29
May
09

Notes #2

# FORMA JAVASCRIPT
def artist=(value)
@artist = value
end
> p1.artist = 90
> p1.artist = 90
> 90

# FORMA JAVA
def setArtist(artist)
@artist = artist
end
> p1.setArtist("holaaaa")
> p1.setArtist("holaaaa")
> "holaaaa"

def artist?
return true
end

29
May
09

Notes #1 – 29 de mayo

A ver si le puedo encontrar un uso bueno de nuevo a este blog… Es que
es un servicio muy lento de alimentar y tiene sus detalles pero bueno
como sea…
Ruby Notes:
——————
mnemonicos
@ es el this
def initialize es como el __init__ de python
puedes inspeccionar dentro de la consola con object.inspect como el
to_source de javascript
los simbolos como en lisp :artist, recuerdos del hunchentoot… –>
compojure

Como recordar el hashrocket ‘=>’? Bueno, es para los hashes…
hola = {
‘asdfasd’ => ‘asdfasdf’
}
O para darle valores a los simbolos…

以上です。(si era asi no? can’t remember the phrase, cannot remember…)

Debe de ser facil lo de alimentar las cosas rapido, escribir una
historia corta de una persona que queria alimentar cosas rapido.

30
Abr
09

Planos de ficciones

Lo único que digo es que cuando estaba hablando con el guardia del coto
de mi casa, de por qué había dejado pasar a una persona, el me dijo que
tenía muy buena memoria y que nunca se le olvidadaba una cara; su amigo
cuya mamá había fallecido mientras estaba en la secundaria, ellos
jugaban mucho en ese tiempo, entonces en el bar por el que pasó mientras
viajaba por el país, lo reconoció y le preguntó: "Tu eres el hijo del
doctor [dt]alacha verdad?", y sí era.

09
Abr
09

Submit una form con AJAX y jQuery en ASP.NET MVC

Me tardé un rato tratando de hacer esto… estos son mis apuntes.
Primero lo que hice fue hacer la vista parcial…


//AJAX: /Project/CreateProject
public ActionResult CreateProject()
{
var db = new AideskDataContext();
Project project = new Project();
return PartialView("CreateProjectControl", project);
}

Y también la parte de POST:


[AcceptVerbs(HttpVerbs.Post)]
public void CreateProjectPOST([Bind(Exclude="ProjectID")] Project project, FormCollection formValues)
{

var db = new AideskDataContext();
UpdateModel(project);
db.Projects.InsertOnSubmit(project);
db.SubmitChanges();

Response.Write("Se acabo esto");
//return JavaScript("alert('yeah!!!');");
}

div id="cpa"> /div < /div

mas mas…


function done() {
//$('form').clearForm();
alert("ya acabe...");
}

fieldset
legendFields/legend
p
label for="ProjectName"ProjectName:/label
%= Html.TextBox("ProjectName")%
%= Html.ValidationMessage("ProjectName", "*")%
/p
p
input type="submit" value="Create" /
/p
/fieldset
% } %