ActiveRecord custom attributes - ruby-on-rails

How can I assign a custom attribute to an ActiveRecord model?
For example, I can do it when querying via:
select("(CASE WHEN wishlist_items.id IS null THEN 0 ELSE 1 END) AS is_wishlisted_by_me").
This adds a custom is_wishlisted_by_me attribute. But what if I already have an instance of an AR model and I want to do:
model.is_wishlisted_by_me = true
this returns a NoMethodError: undefined method
NoMethodError: undefined method `is_wishlisted_by_me=' for #<SIImage:0x007fc8c41c7ef8>
from /Users/Test/.rvm/gems/ruby-1.9.3-p327/gems/activemodel-3.2.13/lib/active_model/attribute_methods.rb:407:in `method_missing'
from /Users/Test/.rvm/gems/ruby-1.9.3-p327/gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:149:in `method_missing'
from (irb):8
from /Users/Test/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
from /Users/Test/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
from /Users/Test/.rvm/gems/ruby-1.9.3-p327/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'

I think you can do it with this way, define attr_accessible in your model:
attr_accessible :user_count
r = User.find_by_sql("select count(*) as user_count from users")
puts r.first.user_count
If a hash will do for you, you may try
User.connection.select_all("select count(*) as user_count from users")
which will return an array of hash like [{:user_count => 1}]

This is what I've done:
after_initialize do
self.is_wishlisted_by_me = nil unless #attributes.key?("is_wishlisted_by_me")
end
def is_wishlisted_by_me
#attributes["is_wishlisted_by_me"]
end
def is_wishlisted_by_me=(value)
#attributes["is_wishlisted_by_me"] = value
end

Related

Rails association extension throws undefined method

I'm trying to create an Active Record anonymous association extension has the documentation explains here. And I've got this models
class Program < ActiveRecord::Base
has_many :reports do
def asdf
"Hello extension"
end
end
end
class Report < ActiveRecord::Base
belongs_to :program
end
But when I test this on my rails c console I've an undefined method error.
Loading development environment (Rails 4.2.5)
2.1.0 :001 > Program.first.reports.asdf
Program Load (0.3ms) SELECT `programs`.* FROM `programs` ORDER BY `programs`.`id` ASC LIMIT 1
NoMethodError: Report Load (0.3ms) SELECT `reports`.* FROM `reports` WHERE `reports`.`program_id` = 1
undefined method `asdf' for #<Report::ActiveRecord_Associations_CollectionProxy:0x000001035e0098>
from /Users/mariowise/.rvm/gems/ruby-2.1.0/gems/activerecord-4.2.5/lib/active_record/relation/delegation.rb:136:in `method_missing'
from /Users/mariowise/.rvm/gems/ruby-2.1.0/gems/activerecord-4.2.5/lib/active_record/relation/delegation.rb:99:in `method_missing'
from (irb):1
from /Users/mariowise/.rvm/gems/ruby-2.1.0/gems/railties-4.2.5/lib/rails/commands/console.rb:110:in `start'
from /Users/mariowise/.rvm/gems/ruby-2.1.0/gems/railties-4.2.5/lib/rails/commands/console.rb:9:in `start'
from /Users/mariowise/.rvm/gems/ruby-2.1.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:68:in `console'
from /Users/mariowise/.rvm/gems/ruby-2.1.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /Users/mariowise/.rvm/gems/ruby-2.1.0/gems/railties-4.2.5/lib/rails/commands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
I'm not trying to share the same extension between many associations, just trying to make this work through the anonymous module (block).
Any ideas?
That's because you retrieved many reports and called the method asdf on them, whereas your method asdf is defined for a single report.
Try this
Program.first.reports.first.asdf

Rails before_destory only works with destroy and not with delete

I am building a rails applications, where in a part of it, I save to the database, payments information. I need to make these payments un-deleteable.
I have created a before_destroy function that kinda works.. but I am having an issue:
here is my code:
class StripePayment < ActiveRecord::Base
belongs_to :user
belongs_to :stripe_card
before_destroy :fail
private
def fail
return false
end
end
When I create a payment and try out my code when delete:
StripePayment.first.destroy returns false and rollback... Which is exactly what I want.
However,
StripePayment.first.delete passes and deletes the object.
I know the deference between delete and destroy. however, I want to be able to prevent this object from being deleted on the DB (on both delete() and destroy() calls.
I tried before_delete and rails gave me back this error:
NoMethodError: undefined method `before_delete' for #<Class:0x007fc1abc37c50>
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-4.0.0/lib/active_record/dynamic_matchers.rb:22:in `method_missing'
from /Users/alybadawy/developing/repos/finish/finish/app/models/stripe_payment.rb:7:in `<class:StripePayment>'
from /Users/alybadawy/developing/repos/finish/finish/app/models/stripe_payment.rb:1:in `<top (required)>'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:423:in `load'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:423:in `block in load_file'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:615:in `new_constants_in'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:422:in `load_file'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:323:in `require_or_load'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:462:in `load_missing_constant'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:183:in `const_missing'
from (irb):1
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
from /Users/alybadawy/.rvm/gems/ruby-2.0.0-p247/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
from bin/rails:4:in `require'
from bin/rails:4:in `<main>'
Any help will be appreciated. Thanks :)
The easiest way is, to define your own delete method
class StripePayment < ActiveRecord::Base
belongs_to :user
belongs_to :stripe_card
before_destroy :fail
def delete
false
end
private
def fail
return false
end
end
If you have conditions, where you want to allow deleteion, you can check for it iy your delete method and call super
that's because delete is one of the functions that skips callbacks in rails
check this out for more info on the subject http://edgeguides.rubyonrails.org/active_record_callbacks.html#skipping-callbacks

Class method returning NoMethodError: undefined method Rails

I am writing a class method to find certain data in my database however I am getting a NoMethodError: undefined method error. I am using Datamapper instead of ActiveRecord. Here is my error output:
NoMethodError: undefined method `get_courses_starting_in' for Course:Class
from /Users/hugo/.rvm/gems/ruby-1.9.2-p318/gems/dm-ar-finders-1.2.0/lib/dm-ar-finders.rb:155:in `method_missing_with_find_by'
from /Users/hugo/Web Development/Rails/connectedtrips/lib/ct_gems/dm-core-1.2.0/lib/dm-core/model/relationship.rb:372:in `method_missing'
from /Users/hugo/Web Development/Rails/connectedtrips/lib/ct_gems/dm-core-1.2.0/lib/dm-core/model/property.rb:249:in `method_missing'
from (irb):24
from /Users/hugo/.rvm/gems/ruby-1.9.2-p318/gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
from /Users/hugo/.rvm/gems/ruby-1.9.2-p318/gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
from /Users/hugo/.rvm/gems/ruby-1.9.2-p318/gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
And here is my class method:
def self.get_courses_starting_in
courses = []
Course.all.each{ |course| courses << course if course.days_till_course_starts == 7}
return courses
end
I hope someone can help. Thanks.
Have you write the code after starting the console? Restart console and check again.

How to load extra fields into a model from thinking-sphinx?

I use thinking-sphinx like this :
class Project < ActiveRecord::Base
define_index do
indexes title
indexes comments.message, as: :comment_message
indexes category_projects.description, as: :category_description
end
class << self
def text_search(word)
ThinkingSphinx.search(word, include: :comments)
end
end
end
When I do this Project.text_search('test') it works but I want to do this :
#projects = Project.text_search('test')
#projects.each do |project|
puts project.comment_message
end
For the moment I have this message :
undefined method `comment_message' for #<ThinkingSphinx::Search:0x000000057e11c0>
from /home/dougui/.rvm/gems/ruby-1.9.3-p194-perf#comment_my_projects/bundler/gems/thinking-sphinx-b293abdbdf0c/lib/thinking_sphinx/search.rb:185:in `method_missing'
from (irb):1
from /home/dougui/.rvm/gems/ruby-1.9.3-p194-perf#comment_my_projects/gems/railties-3.2.6/lib/rails/commands/console.rb:47:in `start'
from /home/dougui/.rvm/gems/ruby-1.9.3-p194-perf#comment_my_projects/gems/railties-3.2.6/lib/rails/commands/console.rb:8:in `start'
from /home/dougui/.rvm/gems/ruby-1.9.3-p194-perf#comment_my_projects/gems/railties-3.2.6/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
So, how to load fields into a model from thinking-sphinx?
I didn't find anything one the doc.
Thanks!
Answered on the TS mailing list as well, but essentially, the fields aren't returned by Sphinx, so you just need to refer to the associations/columns that the fields are built from:
projects.each do |project|
puts project.comments.message.join("\n")
end

rails not allowing me to call a method from inside another method - rails keeps saying the method is undefined

In my model for tutoring sessions, I have code that triggers reminder texts at different times. Everything worked fine, until I tried some refactoring, and now I am having issues.
def send_reminder_text(texts_batch)
texts_batch.each do |text|
page_number = Refugee.find(text.refugee_id)[:last_page]
body_of_text = text[:begin_time].in_time_zone.strftime("Burma Reminder: upcoming session at %I:%M%p beginning on page #{page_number}.
Please email jek2141#columbia.edu to reschedule or cancel the session.")
text.begin_text(body_of_text)
end
end
def self.deliver_pm_reminder_text
texts_batch = TutoringSession.batch_for_pm_reminder_text
send_reminder_text(texts_batch)
end
def self.deliver_just_before_reminder_text
texts_batch = TutoringSession.batch_for_just_before_reminder_text
send_reminder_text(texts_batch)
end
When I call the deliver_just_before_reminder_text function, I get the following error message:
irb(main):006:0> TutoringSession.send_reminder_text
NoMethodError: undefined method `send_reminder_text' for #<Class:0x00000003cfe5d8>
from /app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.1.1/lib/active_record /base.rb:1088:in `method_missing'
from (irb):6
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.1.1/lib/rails/commands/console.rb:45:in `start'
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.1.1/lib/rails/commands/console.rb:8:in `start'
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.1.1/lib/rails/commands.rb:40:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
This is in spite of the fact that the send_reminder_text is clearly defined above.
Your method declaration specifies that the method is on objects of the TutoringSession class:
def send_reminder_text(texts_batch)
But you're trying to call it as if it were a method on the class itself:
irb(main):006:0> TutoringSession.send_reminder_text
Try changing your definition to:
def self.send_reminder_text(texts_batch)

Resources