I have a method "search" in my model, which depending upon the various parameters passed runs an sql query in which i am joining seven tables. but when i am using this method with another named scope then error is shown "undefined method call for array".
but when instead of this search method if i use group of named scope then it works fine.
so how to integrate named scope with that method
It's a little hard to tell for sure without seeing the code. But it sounds like the search method is intended to be called on the Model class and when you chain the named_scope calls either they don't know what to do with the array your search method supplies or your search method doesn't know what to do with the array of records the names scope supplies.
I think your #search method is probably returning something (an Array?) that does not implement some method that named_scope expects. From a quick look into activerecord/lib/active_record/named_scope.rb it appears that named_scope returns a Scope object, which does implement #call (and a bunch of other non-Array methods too). That looks to be why chaining scopes works. So an Array just isn't going to work.
Could you rework your #search method into a named_scope? I realise that you're going to get an unusually (for me, at least) complex definition, but you should then be able to chain your results with other scopes.
Alternatively, how about making your custom search method work so that it returns (and must also take, for chaining before and after to work) a Scope? Probably haarder to do than a big named_scope though.
hey sorry for replying late, but found the answer
I have stored the query in a variable and then passed to the named scope where i do find_by_sql.
hence got the desired result.
Related
I have a Invoice model which accepts_nested_attributes_for :line_items with allow_destroy: true. In my model, in a before_save callback, I can reference the data like this:
self.line_items
Some of the items will be deleted upon save. I want to be able to grab only the items that won't be deleted like this:
self.line_items.where(_destroy: false)
However, this obviously won't work since I am dealing with an unsaved object. So, my question is how do I get the list of items that won't be deleted? I know I could technically iterate through the list and add each applicable item to a new array, but I figure there is something more intuitive. For example, currently I use .sort_by(&:line_number) rather than the SQL .sort(:line_number) for sorting which allows me to sort in memory rather than from SQL. I need the same thing except for a .where clause.
Thanks in advance.
As far as I'm aware, where is aimed specifically at building SQL queries, so you can't use it to deal with in-memory criteria like whether something will be destroyed on save. For that, you can use the methods in the Enumerable module, which is included in the collection object. The sort_by call you mentioned is using that module. In this case, you'd probably use line_items.reject(&:marked_for_destruction?). See the documentation for marked_for_destruction? for more details.
I am trying to understand the none method introduced in Rails4.
Here is the implementation from Rails API
def none
where("1=0").extending!(NullRelation)
end
And I found similar implementation here in Rails3 way.
scope :none, where(:id => nil).where("id IS NOT ?", nil)
Can anyone help me understand how this method was implemented with NullRelation in Rails4 and advantages?
Let's first check ActiveRecord::NullRelation
They basically set to constant values all methods, so whatever you are going to use, won't hit the database.
Remember that when you chain methods over a relation you get a new relation every time, which means, once you hit none, all future methods will try to build a relation from that one. It's easy to imagine that they won't find anything in the database and will just keep returning self (the NullRelation).
In addition, considering that you already linked the current implementation, is pretty clear that they will keep returning an ActiveRecord::Relation, but obviously it won't find anything due to the '1=0' approach. The key point however is in the extending! method, which will overwrite the methods for ActiveRecord::Relation instance (not for all relations, so that's like a singleton instance in Ruby) by forcing it not to hit the database (the exec_queries is replaced with a simple empty array as return value).
I'd like to find object(s) that meets several conditions, and then update the attributes of each object. The problem is that the "where" method doesn't work for this because it returns the result as an ActiveRecord::Relation object, not the object itself, and so update_attributes doesn't work.
But I'm confused because Rails 4 wants you to use where not find, so I don't know how to achieve this. How would you rewrite this code?
Invenborrow.where(inventory_id: inventory_id).where.not(borrow_id: borrow_id).update_attributes(status: "Declined")
Use update_all
Invenborrow.where(inventory_id: inventory_id).where.not(borrow_id: borrow_id).update_all(status: "Declined")
i'm looking for an elegant way to make a model method call. Here is my query:
where("order_id = ?", argument).first
I can't use this query in a scope, because of the first() method, which is chained after the where() method.
So I tried to create the following class method:
def self.find_order(value)
where("order_id = ?", value).first
end
When I use this method twice in my controller action, I get a warning from my IDE, that I should move this query into a scope. When I rename the method without 'find' in the beginning, I also get a warning in my controller, that I shouldn't call more than one method besides find() or new() (I have a another model method calling in this controller action). I know, it isn't a real problem because it works, but I'm interested in writing nice and dry code. I hope it isn't an annoying question, I should fairly say that I'm relatively new to programming.
Thanks in advance!
#{#current_user.allowed_events.size}
#{#current_user.batch_mates.size}
link_to "<span>#{#current_user.related_colleges.size}</span>Colleges".html_safe
in above lines what are these allowed_events.size,related_colleges.size?
are these builtin functions?
Most likely allowed_events and batch_mates are either an association or method on the User model (assuming that's what #current_user references). Take a look in apps/models/user.rb and see if you find anything there.
Those methods are likely returning an ActiveRecord::Relation which is sort like a class wrapper around an array of models, typically returned from a database search. Anyway, the ActiveRecord::Relation class has a size method which is very similar to length or count.
So it's most likely just spitting out the number of allowed events and batch mates that belong to the current user.
As for the #{} that's just triggering Ruby interpolation. You could also do it this way:
= #current_user.allowed_events.size
= #current_user.batch_mates.size
As per the code, current_user is an object of User model. related_colleges and allowed_events could be associations/method/name scope in use model, you need to see your User.rb file in model to get it. I think these are associations (likely has_many) where size is the method to get the count of associated objects