How to add a new property to an object? - ruby-on-rails

I'm trying to add a new property to an object created through my User model.
a = User.find(7)
I get:
#<User id: 7, name: "Ewah", email: "stugnuz#yahoo.it", password_salt: "t4vPG0hgQVQMyIFeri6", persistence_token: "98f0cdfcb9462f3f74b1ae6ef48f0d72a015c6e04adda95fcd0...", login_count: 387, failed_login_count: 0, current_login_at: "2011-03-15 08:03:54", last_login_at: "2011-03-14 23:17:45", current_login_ip: "93.34.49.190", last_login_ip: "93.34.38.47", score: 2726, level: 7, created_at: "2010-10-13 22:33:21", updated_at: "2011-03-28 13:28:40", admin: true, avatar_file_name: "11.jpg", avatar_file_size: 78456, avatar_content_type: "image/jpeg", perishable_token: "PXTFtiMBxcoH3Iv7TmRh", score_this_week: 0, get_news: true, get_notices: true, bio: "Ho perso per strada Minnie anche in onore di Ken Sa...", invitation_id: nil, can_approve: false, no_score: false, facebook_uid: "1052260327", facebook_session_key: "", crypted_password: "05e5080268598607f5d1ece82db1b4d4c6ae12deeb880896ad2...", oauth2_token: "141832835841718|545eae41205d7a2ccb37d7c0-1052260327...", votes_count: 208, post_to_facebook: true, tutorial_step: 2, private: false, posts_count: 31, votes_remaining: 105, votes_this_week: 0, comments_count: 367, ignore: false>
I'd like to add the .votes_cast property to the "a" variable:
a.votes_cast = 5
But when I try to do this I get:
NoMethodError: undefined method `votes_casted=' for #<User:0x102c997f0>
What am I doing wrong?
Thanks,
Augusto

If this is to be a persistent property in your database then you should define a migration to add a column.
If it's just a temporary field in the User model then you can simply add an accessor to class User in app/models/user.rb.
class User < ActiveRecord::Base
attr_accessor :votes_cast
end

Related

Finding a value inside an array

I am stuck with an issue, any help would be appreciated.
I have a rails query
array = Issue.where("tracker_id =? AND project_id = ?",8,140).first.custom_field_values
This returns an array like this :
[#<CustomFieldValue:0x000000074d8b98 #custom_field=#<IssueCustomField id: 4, type: "IssueCustomField", name: "Phase Injected", field_format: "list", possible_values: ["Planning", "Requirements", "Design", "Coding", "Testing"], regexp: "", min_length: nil, max_length: nil, is_required: true, is_for_all: true, is_filter: true, position: 4, searchable: false, default_value: "", editable: true, visible: true, multiple: false, format_store: {"url_pattern"=>"", "edit_tag_style"=>""}, description: "", formula: nil, is_computed: false>, #customized=#<Issue id: 43, tracker_id: 8, project_id: 140, subject: "Cost of rework is not calculated for past sprints", description: "", due_date: nil, category_id: nil, status_id: 1, assigned_to_id: 5, priority_id: 2, fixed_version_id: 1, author_id: 8, lock_version: 3, created_on: "2018-07-26 05:40:19", updated_on: "2018-08-09 10:46:12", start_date: "2018-07-26", done_ratio: 0, estimated_hours: nil, parent_id: 42, root_id: 42, lft: 2, rgt: 3, is_private: false, closed_on: nil, sprint_id: nil, position: nil>, #value="Planning", #value_was="Planning">,.....]
The above array has more then 10 results pasted the first one.
How do I search inside this array for the name = 'Phase Injected' and get the result that is #value which is 'planning'.
Currently I am trying to go inside the array by:
<% array.each do |cf| %>
<% if cf.custom_field.name = "Phase Injected" %>
<%= cf %> #this returns #value
<% end %>
<% end %>
can I not do array.find_by_something and get the value?
Thanks
It returns the active record relation object, not the array in the first place. Yes, it quacks as an array, though.
You should filter the data directly in the database instead of an extremely ineffective array filtering:
Issue.
joins(:issue_custom_fields).
where(tracker_id: 8, project_id: 140).
where('`issue_custom_fields`.`name` = "Phase Injected"')
or, as #Stefan suggests in comments:
Issue.
joins(:issue_custom_fields).
where(tracker_id: 8, project_id: 140).
where(issue_custom_fields: { name: 'Phase Injected' })

After loop always nil in Rails 4

When I try cycle the rails array I have still nil, even when array already defined.
The code:
def gen_address
current_user.accounts.each do |account|
abort(#account.inspect)
next if not account.currency_obj.coin?
if account.payment_addresses.blank?
account.payment_addresses.create(currency: account.currency)
else
address = account.payment_addresses.last
address.gen_address if address.address.blank?
end
end
render nothing: true
end
current_user.accounts have array with three items. abort is there for testing only.
current_user.accounts have:
#<ActiveRecord::Associations::CollectionProxy [#<Account id: 14, member_id: 3, currency: nil, balance: 0.0, locked: 0.0, created_at: "2017-05-23 08:50:11", updated_at: "2017-05-23 08:50:16", in: nil, out: nil, default_withdraw_fund_source_id: nil>, #<Account id: 5, member_id: 3, currency: "btc", balance: 0.0, locked: 0.0, created_at: "2017-05-03 08:37:19", updated_at: "2017-05-03 08:37:19", in: nil, out: nil, default_withdraw_fund_source_id: nil>, #<Account id: 6, member_id: 3, currency: "ltc", balance: 0.0, locked: 0.0, created_at: "2017-05-03 08:37:19", updated_at: "2017-05-03 08:37:19", in: nil, out: nil, default_withdraw_fund_source_id: nil>, #<Account id: 13, member_id: 3, currency: "eth", balance: 0.0, locked: 0.0, created_at: "2017-05-23 08:42:29", updated_at: "2017-05-23 08:42:35", in: nil, out: nil, default_withdraw_fund_source_id: nil>]>
account is always nil
currency_obj is:
module HashCurrencible
extend ActiveSupport::Concern
included do
def currency_obj
Currency.find_by_code(attributes[:currency])
end
end
end
I get this error for row next if not account.currency_obj.coin?, when remove abort:
undefined method `coin?' for nil:NilClass
currenc_obj is nil, so it can't respond to coin? method; check this line:
#<Account id: 14, member_id: 3, currency: nil, balance: 0.0, locked: 0.0, created_at: "2017-05-23 08:50:11", updated_at: "2017-05-23 08:50:16", in: nil, out: nil, default_withdraw_fund_source_id: nil
In your first Account object, the attribute :currency is nil so the method currency_obj will return nil as well.
The variable account has scope only to the loop. So it will be nil outside the loop.

Rails bug: accepts_nested_attributes_for is not updating my has_many association

I have 2 models:
class Book < ActiveRecord::Base
has_many :book_versions
accepts_nested_attributes_for :book_versions, allow_destroy: true
validates_associated :book_versions
class BookVersion < ActiveRecord::Base
has_many :collection_items
has_many :collections, through: :collection_items
belongs_to :book
validates_presence_of :price, :isbn #<-- validates presence
Here are my params. Notice how I leave the price of book_version with name bb blank. This should be firing off the validates_presence_of :price validation in the BookVersion model (but it doesn't):
"book"=>{"title"=>"zzzzzz", "subtitle"=>"", "author_ids"=>[""], "illustrator_ids"=>[""], "award_ids"=>[""], "theme_ids"=>[""], "publication_date"=>"", "imprint_id"=>"1", "language_ids"=>[""], "eng_vers_id"=>"", "book_versions_attributes"=>{"0"=>{"book_id"=>"2848", "name"=>"alt", "isbn"=>"", "price"=>"", "famis_number"=>"", "famis_price"=>"", "weight_in_pounds"=>""}, "1"=>{"book_id"=>"2848", "name"=>"bb", "isbn"=>"123123123123", "price"=>"", "famis_number"=>"", "famis_price"=>"", "weight_in_pounds"=>"1.0", "inventory"=>"08", "id"=>"1030"},
When I do #book.update_attributes(params[:book]) in my controller, none of the book_versions update even though everything seems valid:
>> #book.update_attributes(params[:book])
=> true
>> #book.book_versions
=> [#<BookVersion id: 1030, book_id: 2848, name: "bb", isbn: "123123123123", inventory: "08", price: #<BigDecimal:7fc484885b80,'0.1122E2',18(18)>, famis_price: nil, famis_number: "", weight_in_pounds: #<BigDecimal:7fc4848861c0,'0.1E1',9(18)>, width: nil, height: nil, thickness: nil>, #<BookVersion id: 1031, book_id: 2848, name: "lb", isbn: "12312333333", inventory: "02", price: #<BigDecimal:7fc484886670,'0.2244E2',18(18)>, famis_price: nil, famis_number: "", weight_in_pounds: #<BigDecimal:7fc484886760,'0.1E1',9(18)>, width: nil, height: nil, thickness: nil>, #<BookVersion id: 1032, book_id: 2848, name: "hc", isbn: "111213213131", inventory: nil, price: #<BigDecimal:7fc4848869e0,'0.1212E4',9(18)>, famis_price: nil, famis_number: "", weight_in_pounds: #<BigDecimal:7fc484886d28,'0.1E1',9(18)>, width: nil, height: nil, thickness: nil>]
>> #book.book_versions.map(&:price)
=> [#<BigDecimal:7fc484885b80,'0.1122E2',18(18)>, #<BigDecimal:7fc484886670,'0.2244E2',18(18)>, #<BigDecimal:7fc4848869e0,'0.1212E4',9(18)>]
>> #book.book_versions.map(&:price).map(&:to_f)
=> [11.22, 22.44, 1212.0]
>> #book.save
=> true
>> #book.book_versions.map(&:price).map(&:to_f)
=> [11.22, 22.44, 1212.0] #<-- one of these should be `nil`.
What's going on? The form works perfectly fine when I am creating a Book with many BookVersions. However, it does not update or validate anything when I'm updating an existing book with existing book versions.
This is a continuation of my question here: ActiveRecord: validates_associated does not work when updating model?
UPDATE ====
Uh... I think it's a bug in rails? Look at what happens:
>> #book.update_attributes(params[:book])
=> true
>> #book.book_versions
=> [#<BookVersion id: 1030, book_id: 2848, name: "bb", isbn: "123123123123", inventory: "08", price: #<BigDecimal:7fc487ee9488,'0.1122E2',18(18)>, famis_price: nil, famis_number: "", weight_in_pounds: #<BigDecimal:7fc487ee9118,'0.1E1',9(18)>, width: nil, height: nil, thickness: nil>, #<BookVersion id: 1031, book_id: 2848, name: "lb", isbn: "12312333333", inventory: "02", price: #<BigDecimal:7fc487ee8f88,'0.2244E2',18(18)>, famis_price: nil, famis_number: "", weight_in_pounds: #<BigDecimal:7fc487ee8e98,'0.1E1',9(18)>, width: nil, height: nil, thickness: nil>, #<BookVersion id: 1032, book_id: 2848, name: "hc", isbn: "111213213131", inventory: nil, price: #<BigDecimal:7fc487ee8b50,'0.1212E4',9(18)>, famis_price: nil, famis_number: "", weight_in_pounds: #<BigDecimal:7fc487ee89c0,'0.1E1',9(18)>, width: nil, height: nil, thickness: nil>]
>> #book.update_attributes(params[:book])
=> false
But that is only when I use better errors and freeze the controller before update_attributes. When I actually put #book.book_versions in the controller right before I update the attributes and try running it, it still doesn't work.
So I figured it out with some hackery... For some reason you have to load them in memory first. In order to do this you have to perform some sort of function on the array of book versions. just calling book.book_versions is not enough:
#book.book_versions.sort_by(&:name) # this line is to load the book_versions, without it book_versions will not update!! it's a bug in rails I discovered
if #book.update_attributes(params[:book]) #<-- returns false finally

Convert ActiveRecord::Relation into a usable array

When I call:
preivous_lessons = #item.where("track_id = ?", lesson.track_id)
I get this active record realtion:
[#<CodeLesson id: 2, name: "Python", permalink: "python", lesson_content: "", instructions: "Print your name to the console.", hints: "", starting_code: "\"\"\"\r\nThis is a comment\r\n\"\"\"\r\n\r\nprint(\"Hello, World\"...", language_id: "12", order: 1, track_id: 2, user_id: 1, created_at: "2014-02-14 16:01:12", updated_at: "2014-02-15 21:14:43", visible: true>, #<CodeLesson id: 8, name: "Test Lesson", permalink: "test-lesson", lesson_content: nil, instructions: nil, hints: nil, starting_code: nil, language_id: "26", order: nil, track_id: 2, user_id: 1, created_at: "2014-02-20 19:23:15", updated_at: "2014-02-20 19:23:15", visible: false>]
How do I convert this into a usable array of models so I can do something like this:
preivous_lessons.each do |i|
highest = i.order if i.order > highest
end
As OP confirmed from my comment, that my hint solved his problem, I am putting it as an answer to the post :
preivous_lessons = #item.where("track_id = ?", lesson.track_id)
highest = preivous_lessons.maximum(:order)
Documentation of maximum :
Calculates the maximum value on a given column. The value is returned with the same data type of the column, or nil if there's no row.
preivous_lessons = #item.where("track_id = ?", lesson.track_id).all

error in acts_as_taggable_on_steroids - tags_counts method

The tag_count method gives the same value for all the records
In my GroupsController I have:
#group_blog_tags=#group.blog.blog_posts.tag_counts
where
class Group < ActiveRecord::Base
has_one :blog, :as => :owner, :dependent => :destroy
class Blog < ActiveRecord::Base
has_many :blog_posts, :order => "blog_posts.created_at desc", :dependent =>
:destroy
But it is always fetching the first record in the tags table regardless of which group I choose.
What am I doing wrong?
#group=Group.find(45) => #<Group id: 45, name: "Royal P&O Princess", description:
"Royal P&O Princess the next edit", created_at: "2013-03-04 06:04:57",
primary_photo_id: 807, updated_at: "2013-03-14 07:33:37", tags: "Caribbean,
Nile, Mediterranean", group_memberships_count: 2, group_type: 1,
last_updated_by: 1, content_updated_at: "2013-03-04 11:05:08", activity_points:
0, activity_status: 0, no_memberships_on: nil, owner_id: 28, sponsor_account_id:
65, views: 241, company_id: 0, active: 1, de_flag:0
#group.blog.blog_posts => [#<BlogPost id: 12, created_at: "2013-03-20 05:08:56",
updated_at: "2013-03-20 05:08:56", blog_id: 74, creator_id: 1, title: "South
African Sojourn", text: "<p>\r\n\tSouth African Sojourn</p>\r\n", comments_count:
0, created_at_year_month: 201303, cached_tag_list: "Africa, Veldt", rating_count:
0, rating_total: 0, rating_avg: #<BigDecimal:b2de1978,'0.0',4(8)>, views: 1,
source: nil, link: nil, guid: nil, tagline: nil, creator_type: "Profile",
num_positive_votes: 0, num_negative_votes: 0, net_helpful: 0, best_image: nil,
active: 1>, #<BlogPost id: 11, created_at: "2013-03-20 03:46:07", updated_at:
"2013-03-20 03:46:07", blog_id: 74, creator_id: 1, title: "African safari", text:
"<p>\r\n\tAfrican safari Africa, Safari Afric...", comments_count: 0,
created_at_year_month: 201303, cached_tag_list: "Africa, Safari, Veldt",
rating_count: 0, rating_total: 0, rating_avg: #<BigDecimal:b2de1518,'0.0',4(8)>,
views: 1, source: nil, link: nil, guid: nil, tagline: nil, creator_type:
"Profile", num_positive_votes: 0, num_negative_votes: 0, net_helpful: 0,
best_image: nil, active: 1>, #<BlogPost id: 2, created_at: "2013-03-04 06:34:53",
updated_at: "2013-03-04 06:34:53", blog_id: 74, creator_id: 28, title: "New blog
post", text: "<p>\r\n\tNew blog post</p>\r\n", comments_count: 4,
created_at_year_month: 201303, cached_tag_list: "New blog post", rating_count: 0,
rating_total: 0, rating_avg: #<BigDecimal:b2de1414,'0.0',4(8)>, views: 7, source:
nil, link: nil, guid: nil, tagline: nil, creator_type: "Profile",
num_positive_votes: 1, num_negative_votes: 0, net_helpful: 1, best_image: nil,
active: 1>]
#group.blog.blog_posts.tag_counts => [#<Tag id: 1, name: "acticity
stream message">]
Trying another group:
Group.find(40).blog.blog_posts.tag_counts => [#<Tag id: 1, name: "acticity
stream message">]
Its always fetching the same records as result!
I think a group "belongs_to" a blog, and not "has_one".
Edit
You have to specify the relation between group and blog. It can be this cases:
A group has_one blog, a blog belongs_to a group
A group has_many blogs, a blog belongs_to a group
A group belongs_to a blog, a blog has_one group
A group belongs_to a blog, a blog has_many groups
A group has_one_and_belongs_to_many blogs, a blog has_one_and_belongs_to_many groups
A x belongs_to y implies you have a y_id in your x table.
A x has_one y or x has_many y specify the number of y for each x.
A x has_and_belongs_to_many y implies x has many y and y has_many x.

Resources