Kaminari doesn't work If my query is in the model - ruby-on-rails-3

I have my mongoid query in the model
def self.get_result collection_name, hash_params, page, per_page
self.collection_name = collection_name
#result_pg = self.where(hash_params).page(page).per(per_page)
end
I have it here because my collection names are passed as parameters and I don't have models for all my collection. Instead I have one model and I set its name dynamically based on the request parameter.
My controller code
Collection.get_result params[:state], hash_param, params[:page], params[:per]
My View code
<%= paginate #result_pg %>
When I use the above code I get
undefined method `current_page' for nil:NilClass ERROR

I think the variable is being lost when you call it in the model. Instead, have it return the object back to you like so:
return self.where(hash_params).page(page).per(per_page) // put this in your model
Then, I'm the controller, connect the pieces:
#result_pg = Collection.get_result params[:state], hash_param, params[:page], params[:per]
// in your controller like so
Right now, the controller isn't setting #result_pg, that is why it is nil and you are getting the nil error. Try this and let me know if that worked out for you.
Updated
Ok, as for the reason this happens. When Rails loads a controller, the variables that you declare with a # symbol, like #bologna will be passed to the view and something will be done with them.
On the other hand, you are not technically declaring and instantiating that variable in the controller, you are doing it in the model, as per your source code that you posted above. Declaring the variable there can be done but it isn't useful because the controller has no idea that it even happened. When you tell the Class Collection to perform a method, usually you have that method return something back to you, if you don't, then the variable is lost.
It is similar to me asking someone to go to the store and buy me some groceries, you did the right things, giving the method all the information it needed, passing it the right variables to do its job correctly, but not telling it to actually come back with them, is where the error occurs. In your method, the groceries get purchased at the store and left there. The revised function I wrote for you tells it return with the groceries and put them in the variable #result_pg. The variable is declared in the Controller like it is supposed to be.
So in short, anything you want to have accessible in the view, needs to be declared in the controller. And anytime you want something back from a method, always have it return the information to you.
Also, it isn't entirely necessary to even have the method call to the Class Collection. In a project of my own where I use Kaminari, I just simply do the whole call from in the controller like so:
#notes = current_user.notes.page params[:page]
// My Application has :users that have_many :notes
So you could simplify it that way if you want, but the method that I suggested that fixes it the way you are doing it will work too, however you prefer.
I hope my explanation helped and wan't too long winded.

Related

Defining onchange methods in odoo if on_change is defined on the model

I'm trying to define an onchange event on the field amount and line_cr_ids.amount on account.voucher but any definition like this:
#api.one
#api.depends('line_cr_ids', 'line_cr_ids.amount')
def _line_amount_onchange(self):
...
Or
#api.one
#api.onchange('amount')
def _onchange_amount(self):
...
Are never called, I noticed that a on_change parameter is defined on those fields in the view. Does it means the only way to get the onchange is to redefine the one already defined?
Yes, you need to redefine the on_change method called by the view.
Or change the view itself removing it as attribute.
Ok, so I solved my problem as I didn't want to remove the on_change attributes... There is a better and more stable way of working than using the api.onchange decorator for now. I guess the decorators could get more stable over time but in my case it didn't fit at all. It would get called and sometimes it wouldn't... Children of object do not have access to parent object because the ORM doesn't allow it... ask me why I don't know...
That said the holy grail is to override the onchange method on the object.
I noticed that whenever something happens, it would call the onchange method on my account.voucher object.
So the solution is to create a method:
class AccountVoucher(models.Model):
...
#api.model
def onchange(self, ids, values, field, fields):
result = super(AccountVoucher, self).onchange(
values, field, fields
)
#...
# do whatever you want here change result and return it
#...
result
This way, all changes are visible and it never miss. It also call other onchange when calling super so you don't miss anything. If you need to use decorators anyway, it shouldn't stop anything from working. In other words... while overriding onchange, you're getting at the root of the problem and nothing stops you from getting things done.

How to manually instantiate ActiveRecord truncated objects?

Working with ActiveRecord and JRuby, I try to invoke a stored procedure on a Database. Using the underlying Java Library I reached a point where I have a hash with the columns specified in the select.
Now I'd like to use this hash to have ActiveRecord models, but I'd like them to look like if I did a classic Model.select(columns).all (with only the columns values, errors when trying to reach the other ones and readonly).
There must be something inside of AR to do this but I can't find anything and all my search leads to all the basic "fetch" tutorials ...
OK so I kept digging in Rails code and figured out my answer was the instantiate method.
The idea is if you are inside a model called MyModel and do this
object = instantiate(value1: 1, value2: 'ok')
you will have an instance of the MyModel class with theses attributes defined. If the model is supposed to have more columns, they are not defined. The object is readonly.

Use a Class name stored in a variable to call a Class method?

I'm probably over-thinking this/wasting time trying to avoid a bit of conditional code - so I thought I would ask. I've seen some other questions # this sort of thing but they were using php or some other language.
At the most basic, can I do something like this (I know the syntax is wrong):
Class * var = #"Playback_Up";
// call Class method to get default settings
NSMutableDictionary * dict = [var getPlaybackDefaults];
Why do I want to do this? To avoid a bunch of conditionals. I have an app where a using can select from a range of playback "types" - each type is handled by a subclass of a "Playback" class. It would be convenient to store the class names in an array and then when a selection is made (from a tableView) call the selected class, create an instance of it, etc.
Is this possible or am I digging myself into a hole here?
The correct syntax for your first line is:
Class var = NSClassFromString(#"Playback_Up");
The rest is fine, and I use this kind of technique more frequently than you might imagine.
(Except that "Playback_Up" should never be the name of a class of course.)
EDIT: Do note Paul.s's comment below. Using +class is preferred if you can hard-code the class at compile time.

Create callback executing foobar twice

My model looks like this:
after_create :foobar
after_update :foobar
def foobar
update_attributes(:foo => 'bar')
end
Whenever I create an object. It calls foobar (after_create callback). But it also automatically triggers the after_update callback.
Basically, when I create an object its calling foobar twice.
How can I prevent this?
In after_create you're calling update_attributes() which triggers the after_update callback.
Basically you're calling it twice. You need to figure out what the proper flow is for your program, and make it such that foobar only gets called once. Right now, the code you've written is executing as designed.
One suggestion would be using before_[action] attributes instead to modify the fields in the incoming object. That way the object only gets saved once. The way you've written it, new objects get saved twice - once when they're created, and once when they're updated via update_attributes.
I see that this is example code, but I'm not sure how, in after_update, since you explicitly make ANOTHER update, how this isn't getting wrapped up in an infinite loop. Might be able to give a better answer if you post actual code.

Object methods and stats - the best object oriented design approach question

I need to write some instance method, something like this (code in ruby):
def foo_bar(param)
foo(param)
if some_condition
do_bar(param)
else
do_baz(param)
end
end
Method foo_bar is a public api.
But I think, param variable here appears too many times. Maybe it would be better to create an private instance variable and use it in foo, do_bar and do_baz method? Like here: (#param is an instance variable in ruby, it can be initialized any time)
def foo_bar(param)
#param = param
foo
if some_condition
do_bar
else
do_baz
end
end
Which code is better? And why?
Is param replacing part of the state of the object?
If param is not changing the object state then it would be wrong to introduce non-obvious coupling between these methods as a convenience.
If param is altering the state of the object then it may still be bad practice to have a public api altering the state - much better to have a single private method responsible for checking and changing the state.
If param is directly setting the state of the object then I would change the instance variable here but only after checking that the new state is not inconsistent
The first version should be preferred for a couple of reasons. First, it makes testing much easier as each method is independent of other state. To test the do_bar method, simply create an instance of its containing class and invoke the method with various parameters. If you chose the second version of code, you'd have to make sure that the object had all the proper instance variables set before invoking the method. This tightly couples the test code with the object and results in broken test cases or, even worse, testcases that should no longer pass, but still do since they haven't been updated to match how the object now works.
The second reason to prefer the first version of code is that it is a more functional style and facilitates easier reuse. Say that another module or lambda function implements do_bar better than the current one. It won't have been coded to assume some parent class with a certain named instance variable. To be reusable, it will have expected any variables to be passed in as parameters.
The functional approach is the much better approach ... even in object oriented languages.
If you do not need param outside of the foo_bar method the first version is better. It is more obvious what information is being passed around and you are keeping it more thread friendly.
And I also agree with Mladen in the comment above: don't add something to the object state that doesn't belong there.