How to pass ActiveRecord model class to Resque - ruby-on-rails-3

Let's say I have the following Resque job:
class Archive
#queue = :file_serve
def self.perform(repo_id, branch = 'master')
repo = Repository.find(repo_id)
repo.create_archive(branch)
end
end
What if I wanted to make this more generic by passing an object id and the object's class so that I can do something like this:
class Archive
#queue = :file_serve
def self.perform(object_class, object_id, branch = 'master')
object = object_class.find(object_id)
object.create_archive(branch)
end
end
This doesn't work, obviously, and I don't have a sense for what I should be doing, so if anyone can give some guidance, that would be really appreciated!

I would pass the name of the class to the job, rather than the class itself. Then you could call constantize on the name to get the class back, and call find on it. eg.
def self.perform(class_name, object_id, branch = 'master')
object = class_name.constantize.find(object_id)
object.create_archive(branch)
end

Related

Django - id null - foreign key error

Error:
app_a.desc_id may not be NULL
I believe my problem is I'm not passing the id from formB to formA when I save. please please lead me to a solution for this problem.
Here's my view:
def form(request):
if request.method == 'GET':
formB = BForm()
formA = AForm()
return render(request,r'app/form.html',{'formA':formA,'formB':formB})
elif request.method == 'POST':
formA = AForm(request.POST)
formB = BForm(request.POST)
formB.save()
formA.save()
return HttpResponseRedirect('/log')
Here are my models:
# Descprition
class B(models.Model):
id = models.AutoField(primary_key=True)
description = models.CharField(max_length=50)
# Title
class A(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField('Name',max_length=20)
desc = models.ForeignKey(B)
and here is my form:
class BForm(forms.ModelForm):
class Meta:
model = B
fields = ['description']
class AForm(forms.ModelForm):
class Meta:
model = A
fields = ['name']
Your program has multiple errors but the main problem for this is because desc is a foreign key in class A that points to class B, and you don't have null=True on it, meaning you never want that field to be empty. In other words, each instance of A should have a foreign key desc.
If you just save() both forms, formA tries to save an instance of A, without having a value for desc field, hence the error. You should assign the instance that formB creates to the instance that formA creates:
new_b = formB.save()
new_a = formA.save(commit=False)
new_a.desc = new_b
new_a.save()
Other problems in your program including never called form.is_valid(), having redundant id fields(django would create one for you). I suggest you read django tutorial first before jumping into coding. It would save a lot of time like figuring out errors like this.

Rails - use object oriented "advanced"

I would like to maintain my code DRY, then I want to transform this pseudo-code:
def aMethod
a = aModel.find(2)
b = a.getVariable
a.setVariable = c
end
in something like this
def aMethod
anotherMethod(aModel, getVariable)
end
def anotherMethod(model, var)
a = model.find(2)
b = a.var
a.var = c
end
In my tests, seems that there is no problem for the model, but for the getVariable (i.e. accessing the variable of the model) it doesn't work: undefined local variable or method
Any ideas?
You likely want to use send, if I understand what you're trying to do, e.g.,
def anotherMethod(model, var_sym)
a = model.find(2)
b = a.send(var_sym)
a.send("#{var_sym}=", c)
end
anotherMethod(aModel, :getVariable)
(With the caveat that I don't know what a, b, or c are, or should do, since they're locals in the OP.)

Increment integer on save in Rails 3?

I have the following code in my Rails 3 application:
def like
#suggestion = Suggestion.find(params[:id])
Suggestion.update_all("votes = (votes + 1)")
redirect_to suggestions_url
end
def dislike
#suggestion = Suggestion.find(params[:id])
Suggestion.update_all("votes = (votes - 1)")
redirect_to suggestions_url
end
It's working, but rather than updating the current suggestion it's updating them all. So I changed it to:
def like
#suggestion = Suggestion.find(params[:id])
#suggestion.update_all("votes = (votes + 1)")
redirect_to suggestions_url
end
def dislike
#suggestion = Suggestion.find(params[:id])
#suggestion.update_all("votes = (votes - 1)")
redirect_to suggestions_url
end
but then I get:
undefined method `update_all' for #<Suggestion:0x007f87c2b918a0>
So then I tried #suggestion.update_attribute(:votes, '1') but that resets the value to 1 instead of incrementing it.
What's the correct way to achieve this? I just want the integer (votes) of the current suggestion to increment/decrease by 1 on each save.
I've also tried the following with no luck:
def like
#suggestion = Suggestion.find(params[:id])
#suggestion.increment(:votes)
redirect_to suggestions_url
end
This seems more suitable in the model. I suggest creating a like method inside the model like so:
def like
self.increment!(:votes)
end
Now you can do something like this:
#suggestion = Suggestion.find(params[:id])
#suggestion.like
Note: increment!, with the exclamation point also performs the save action
A couple things. It sounds like what you want is a controller action that increments an attribute by one. You were probably closest with the code
#suggestion.update_attribute(:votes, '1')
If you check the documentation for that method, it sets the value of the attribute votes to the second arguement, the string '1', on the object, #suggestion, and its corresponding row in the database. Instead of setting it to '1', you want to set it to the incremented value:
#suggestion.update_attribute(:votes, #suggestion.votes + 1)
Ethan suggested using the convenience method, increment!, which works just the same.
Now, if you wanted to actually auto-increment each time the object gets saved (as in something else about the object gets altered, you'd want to use the :before_save callback with increment without the bang.

Matlab Object Oriented composition, aggregation

i'm writing my first MATLAB O-O application and i'm confused about the implementation of compositions, aggregations and relationships in general.
My question is: how to implement an aggregation or an association one-to-many in matlab? Where i can take some examples?
Moreover, i'm using ArgoUml to design my application, is there any plugin to automatic code generation in matlab?
Thanks in advance
Here is a quick example of class association. The scenario consists of a course that can have many students enrolled:
Student.m
classdef Student < handle
properties
name
end
methods
function obj = Student(name)
if nargin > 0
obj.name = name;
end
end
function delete(obj)
fprintf('-- Student Destructor: %s\n',obj.name);
end
end
end
Course.m
classdef Course < handle
properties
name %# course name
std %# cell array of students
end
properties(Access = private)
lastIdx = 1;
end
methods
function obj = Course(name, capacity)
obj.name = name;
obj.std = cell(capacity,1);
end
function addStudent(obj, std)
if obj.lastIdx > numel(obj.std)
fprintf(2, 'Sorry, class is full\n');
return
end
obj.std{obj.lastIdx} = std;
obj.lastIdx = obj.lastIdx + 1;
end
function printClassRoster(obj)
fprintf('Course Name = %s\n', obj.name);
fprintf('Enrolled = %d, Capacity = %d\n', ...
obj.lastIdx-1, length(obj.std));
for i=1:obj.lastIdx-1
fprintf('ID = %d, Name = %s\n', i, obj.std{i}.name);
end
end
end
end
And here is a code to test the above classes:
c = Course('CS101', 3);
for i=1:4
name = sprintf('amro%d',i);
fprintf('Adding student: %s\n', name)
c.addStudent( Student(name) )
end
fprintf('\nClass Roster:\n=============\n')
c.printClassRoster()
fprintf('\nCleaning up:\n')
clear c
The output:
Adding student: amro1
Adding student: amro2
Adding student: amro3
Adding student: amro4
Sorry, class is full
-- Student Destructor: amro4
Class Roster:
=============
Course Name = CS101
Enrolled = 3, Capacity = 3
ID = 1, Name = amro1
ID = 2, Name = amro2
ID = 3, Name = amro3
Cleaning up:
-- Student Destructor: amro1
-- Student Destructor: amro2
-- Student Destructor: amro3
You may have a look at Object-Oriented Programming in MATLAB and in the documentation refer to Object-Oriented Programming.
I suggest to have a closer look Value or Handle Class — Which to Use
. To make it short, handle classes let you pass references around whereas value classes are always a copy of the original object.
I'd be surprised to find a plugin for ArgoUml, as MATLAB is mainly used by engineers and not software developers.

ROR Observer doesnt work

OrderItem observer doenst calculate total sum when updating OrderItem :((
what's wrong?
class OrderItemObserver < ActiveRecord::Observer
def after_save(order_item)
order_item.order.total_sum = order_item.order.order_items.collect{|i| i.price.to_i}.sum
end
end
listed in application.rb
config.active_record.observers = :order_observer, :order_item_observer
The result is being calculated then discarded as you are not saving the result.
class OrderItemObserver < ActiveRecord::Observer
def after_save(order_item)
order = order_item.order
order.total_sum = order.order_items.collect{ |i| i.price.to_i }.sum
order_item.save
end
end
Value is now saved. The order variable is just to tidy things up a little.