class Item < ActiveRecord::Base
attr_accessible :name, :item_reviews
has_many :item_reviews, :dependent => :destroy
accepts_nested_attributes_for :item_reviews
end
class ItemReview < ActiveRecord::Base
attr_accessible :price, :value_for_money
belongs_to :item
end
I am using a multi-model form for post request of a new item (with review). I am using following parameters in post request:
{"utf8"=>"✓",
"authenticity_token"=>"oZZ6T5bxWHnSiO2Tdz3eFUVCrRH3lzzxdBpuJjlWcho=",
"item"=>{"name"=>"test",
"item_reviews"=>[{"value_for_money"=>"1",
"price"=>"25000"}]},
"commit"=>"Submit"}
But I got following error while saving:
ItemReview(#89032230) expected, got ActiveSupport::HashWithIndifferentAccess(#77848120)
I suspect array in item_reviews as the culprit, so I did the following:
params[:item][:item_reviews] = params[:item][:item_reviews][0]
but then I started getting following error:
ItemReview(#87446700) expected, got Array(#75744590)
How can I solve it?
Related
I've tried wrapping my mind around how to navigate the associations I want, but I can't seem to figure it out. I'm trying to get all the Posts given a Tag. Each Post currently has a title and body text, both of which are represented as TaggedText. Each TaggedText can have many unique tags — like tagging multiple people/pages in a Facebook post (uniqueness is enforced in the model when saving an instance).
class Tag < ActiveRecord::Base
has_many :tagged_texts, through: :tag_ranges
end
class Post < ActiveRecord::Base
has_many :tagged_texts
end
class TaggedText < ActiveRecord::Base
# Each TaggedText cannot have more than one of each tag
has_many :tags, through: :tag_ranges
belongs_to :post
end
class TagRange < ActiveRecord::Base
# TaggedText cannot have more than one of each tag
belongs_to :tagged_text
belongs_to :tag
end
I tried joining the tables, but I get the error Association named 'tag_ranges' was not found on Post:
def get_posts_by_tag(tag, page, posts_per_page)
Post
.joins(:tagged_texts)
.joins(:tag_ranges)
.joins(:tags)
.where('tag.id = ?', tag.id)
.uniq
.limit(posts_per_page)
.offset(page - 1)
.to_a
end
What am I missing to get the query to work — or should I restructure my models and associations somehow?
As you error states, you need to add a tag_ranges association to your Post model. I've also added a few associations that you may or may not find useful, and one that will simplify your query greatly. Not that your TagRange class's associations are fine as is.
class Tag < ActiveRecord::Base
has_many :tag_ranges # need this association in order to get tagged_texts
has_many :tagged_texts, through: :tag_ranges
has_many :posts, -> { uniq }, through: :tagged_texts # posts with the given tag
end
class Post < ActiveRecord::Base
has_many :tagged_texts
has_many :tag_ranges, through: :tagged_texts # Post now has association named 'tagged_ranges'
has_many :tags, -> { uniq }, through: :tag_ranges # tags that given post has
end
class TaggedText < ActiveRecord::Base
has_many :tag_ranges # all tag ranges for a tag text
has_many :tags, through: :tag_range
belongs_to :post
end
And now, your query to get all the posts for a tag:
def get_posts_by_tag(tag, page, posts_per_page)
tag.posts.limit(posts_per_page).offset(page - 1).to_a
end
Hopefully this helps!
I am facing a weird behaviour. This is my scenario.
class Message < ActiveRecord::Base
belongs_to :user, :foreign_key => "from_user_id"
has_many :message_recipients, :include => [:user], :dependent => :destroy
has_many :recipients, :through => :message_recipients, :source => :user
end
class MessageRecipient < ActiveRecord::Base
belongs_to :user
belongs_to :message, :include => :message_recipients
end
class User < ActiveRecord::Base
acts_as_paranoid
has_many :message_recipients
end
I am creating a new message and pushing value to its recipients.
#message=Message.new(:body => "Hi",:from_user_id => session[:user])
#message.recipients.push(User.find(params[:message_recipient_id]))
#message.save
The above operation saves the record in message correctly but fails to trigger the message_recipient record. But if i perform the above code removing the acts_as_paranoid gem, then it works fine. Is there any work around to solve this issue?
Solution 1:
Instead of calling new on Message model we can use create on Message model. So the record will be created and then i can push the data inside the recipients.Its like creating parent record and using its id i am creating child record. So there is no need for trigerring and it works fine.
Suggestions are welcome.
It works fine with rails 3.2.12 but fails with rails 3.2.13. I am confused with this behaviour.
I'm trying to create nested attributes as outlined in this railscast http://railscasts.com/episodes/167-more-on-virtual-attributes?view=asciicast
In my example, I am trying to associate an activity to an image, so I have a structure of activity -> activity_image -> image.
When I save my activity, rails creates the activity and the image, but I'm not getting the intersecting table of activity_image being saved. Of course, I never actually tell rails to save this, but neither does the railscast I'm following.
Is there some way this is supposed to be defined in the models? What have I got wrong?
class Activity > ActiveRecord::Base
attr_accessible :title, :description, :activity_image_url
belongs_to :user
has_many :activity_images
has_many :image_urls, :through => :activity_images
#validates_presence_of :title, :description, :url
attr_accessor :activity_image_url
after_save :assign_image
private
def assign_image
if #activity_image_url
self.activity_image_url = ImageUrl.find_or_create_by_url(#activity_image_url)
end
end
end
I know all the security reasons behind why mass-assigning is bad, what I cant figure out is why my app is trying to do a mass assign.
I am just trying to create a new record of my Section model and I am getting the "Can't mass-assign protected attributes" error. Below are the possible involved models. Can someone please explain to me how this is a mass-assigning? I am new to rails, so I could be missing something very simple.
class Section < ActiveRecord::Base
belongs_to :project
belongs_to :type, :foreign_key => 'type_id', :class_name => 'SectionType'
attr_accessor :order
end
class SectionType < ActiveRecord::Base
attr_accessible :name, :template
end
class Project < ActiveRecord::Base
has_many :sections
attr_accessible :description, :name, :short, :status, :subtitle, :version
def to_param
return name.gsub(/\s+/, '%20')
end
end
Any help would be greatly appreciated, I am new to rails and know this is probably a simple problem, but I have been trying to find an answer and can not.
If you're attempting to create a new Section object and that's failing, that'd be because you don't have any attributes listed as accessible inside that model. You will need to do that, using a similar call to attr_accessible as the one you have in your Project model already.
I get this error "WARNING: Can't mass-assign protected attributes: races_attributes"
, when following this http://railscasts.com/episodes/196-nested-model-form-part-1 on rails 3.
Where Races are a component of Events. This is my models/race.rb:
class Race < ActiveRecord::Base
belongs_to :event
attr_accessible :name, :unit
end
This is my models/event.rb:
class Event < ActiveRecord::Base
has_many :races, :dependent => :destroy
accepts_nested_attributes_for :races
attr_accessible :name, :date, :description, :location_name, :address_one, :address_two, :city, :state, :zip, :active, :races_attributes
end
Any Ideas?
Shorter than using attr_accessible, safer than using whitelist_attributes: attr_protected
Just indicate the protected attributes, and Rails will infer that all others can be mass-assigned:
class MyClass < ActiveRecord::Base
attr_protected :id
end
(I always have way more attributes that I want mass-assigned than the ones I want protected.)
attr_accessible specifies that you can not mass-assign attributes, using save method, for example. So, if you change an attribute that is not defined with attr_accessible, you will get a warning because it will not actually be saved in the database.