Remove current model instance from AR:Relation - ruby-on-rails

I am creating an instance method on a model which returns instances of the same model. How can I ensure that the instance of the model that the method is being called upon is not part of the output?
My code is like this at the moment:
def other_versions(include_current = true)
if include_current
Coaster.where(order_ridden: order_ridden)
else
#coaster.other_version_count // Need this to exclude the current instance.
end
end

I'm not sure I understood, but would this help?
def other_versions(include_current = true)
query = Coaster.where(order_ridden: order_ridden)
query = query.where("id != ?", id) unless include_current
query
end

Related

Rails complicated class method chaining

How do you write a complicated class method that applies to whatever it's being chained to? Let me explain: a simple class method such as:
def self.despondent
where(despondent: true)
end
can be easily chained:
User.desperate.despondent.disillusioned
But what if you've got a complicated class method such as:
def self.friendly_dogs(user)
#dogs1 = Dog.none
#dogs2 = Dog.none
if user.has_dog
users = User.friends.where(has_dog: true)
#dogs1 = Dog.where(user_id: users.ids)
end
if user.wife.has_dog
users = user.wife.friends.where(has_dog: true)
#dogs2 = Dog.where(user_id: users.ids)
end
return #dogs1.or(#dogs2).distinct
end
How would you write this so you can place it anywhere in the chain? And in the following example would select only the friendly_dogs from all poodles that are 1 year old:
#dogs = Dog.where(breed: "poodle").where(age: "1").friendly_dogs.paginate(page: params[:page])

grails - org.hibernate.QueryException (could not resolve property)

I'm trying to get the list of a specific rental from the current user.
Code in controller:
def index() {
if (isLoggedIn()) {
String username = getPrincipal().username
def accountInstance = Account.findByUsername(username)
def rentalInstanceList = Rental.findAll("from Rental as r where r.account_id=:accountid", [accountid: accountInstance.id])
}
}
account_id is a foreign key.
After running I get the error:
could not resolve property: account_id of: ers.Rental
What am I doing wrong?
Generally, in HQL you have to use the field names as defined in your domain classes. So, your query should look like:
def list = Rental.findAll("from Rental where accountId=:accountid", [accountid: accountInstance.id])
or
def list = Rental.findAllByAccount accountInstance
or even
def list = Rental.findAllByAccount getPrincipal()
if the return type of getPrincipal() has the id field.
findAll is not limited to instances of the calling class so I use executeQuery instead. https://stackoverflow.com/a/8916483/5011228

Looping through object and blanking out fields

I have this constant to hold all dates fields:
DATE_FIELDS = [:a_effective_on, :a_expire_on,
:field_effective_on, :field_expire_on,
:line_manager_effective_on, :line_manager_expire_on,
:officer_effective_on, :officer_expire_on,
:regional_effective_on, :regional_expire_on]
I want to loop over an object and remove a date if it has a value.
Is this valid?:
#copy_to.DATE_FIELDS.each do |_date|
# remove dates here
end
I am getting a nil class for id error.
DATE_FIELDS.each do |field|
#copy_to.send("#{field}=".to_sym, nil) if #copy_to.send(field)
end
When you put a constant in your class like this, it exists at the class level. Access it with YourClassName::DATE_FIELDS if you're outside the class, or just DATE_FIELDS if you're inside the class.
This is how i would do it:
#instance method in your class
def clear_all_date_fields
atts = {}
DATE_FIELDS.each{|f| atts[f] = nil}
self.attributes = atts
end
Now you can do
#copy_to.clear_all_date_fields
note that this doesn't save #copy_to. You can save it afterwards, or put the save into the method (though i think it's better to have it not saving automatically).

How to mimic asp.net get set in rails

I am trying to mimic asp.net get{} set{} in rails, here is what i tried in my controller:
def get_segment=(segment)
if params[:s] != nil
segment = params[:s]
else
segment = "personal"
end
end
Then i am trying to access it like this:
#something = get_segment
But it always returns as nil.
How can i do this?
Thanks
Why are you using get segment=(segment)?
look like what you are wanting to do is test params[:s], so the = is uncessary, as is the segment parameter.
def get_segment
if params[:s] != nil
params[:s]
else
"personal"
end
end
I think this would give you what you want.
If you just want to mimic get{} set{} in C#, the property Segment
private string _segment;
public string Segment {
get { return _segment; }
set { _segment = value; }
}
is written as followed in Ruby:
# get
def segment
#segment
end
# set
def segment=(value)
#segment = value
end
# if you don't have additional logic, you can just write
attr_accessor :segment
Then you can use some_instance.segment to retrieve the value and some_instance.segment = some_value to modify the value.
According to your code sample above, you want to fetch s parameter with a default value if it doesn't exist. You should define a getter, not in the setter form as you have provided.
def get_segment # or just "segment"
params[:s] || "personal"
end

Using a method while looping through an array in ruby

I am using ruby-aaws to return Amazon Products and I want to enter them into my DB. I have created a model Amazonproduct and I have created a method get_amazon_data to return an array with all the product information. When i define the specific element in the array ( e.g. to_a[0] ) and then use ruby-aaws item_attributes method, it returns the name I am searching for and saves it to my DB. I am trying to iterate through the array and still have the item_attributes method work. When i don't define the element, i get this error: undefined method `item_attributes' for #Array:0x7f012cae2d68
Here is the code in my controller.
def create
#arr = Amazonproduct.get_amazon_data( :r ).to_a
#arr.each { |name|
#amazonproduct = Amazonproduct.new(params[:amazonproducts])
#amazonproduct.name = #arr.item_attributes.title.to_s
}
EDIT: Code in my model to see if that helps:
class Amazonproduct < ActiveRecord::Base
def self.get_amazon_data(r)
resp = Amazon::AWS.item_search('GourmetFood', { 'Keywords' => 'Coffee Maker' })
items = resp.item_search_response.items.item
end
end
Thanks for any help/advice.
I'm not familiar with the Amazon API, but I do observe that #arr is an array. Arrays do not usually have methods like item_attributes, so you probably lost track of which object was which somewhere in the coding process. It happens ;)
Try moving that .item_attributes call onto the object that supports that method. Maybe amazonproduct.get_amazon_data(:r), before its being turned into an array with to_a, has that method?
It's not quite clear to me what your classes are doing but to use #each, you can do something like
hash = {}
[['name', 'Macbook'], ['price', 1000]].each do |sub_array|
hash[sub_array[0]] = sub_array[1]
end
which gives you a hash like
{ 'name' => 'Macbook', 'price' => 1000 }
This hash may be easier to work with
#product = Product.new
#product.name = hash[:name]
....
EDIT
Try
def create
#arr = Amazonproduct.get_amazon_data( :r ).to_a
#arr.each do |aws_object|
#amazonproduct = Amazonproduct.new(params[:amazonproducts])
#amazonproduct.name = aws_object.item_attributes.title.to_s
end
end

Resources