Rails 3.1.rc1 and accept_nested_attributes_for - ruby-on-rails-3

I have the following models:
class Survey < ActiveRecord::Base
set_primary_key :survey_id # I'm using external DB
belongs_to :user #UPDATED
has_many :questions, :dependent => :destroy
accept_nested_attributes_for :questions
end
class Question < ActiveRecord::Base
set_primary_key :question_id # I'm using external DB
belogns_to :survey
end
If I go to rails console and save a model:
>> params = {"title"=>"Survey 1", "questions_attributes"=>{"0"=>{"title"=>"Question 2"}}}
>> survey = User.first.surveys.build(params) #UPDATED
>> survey.questions.size
=> 2
>> survey = User.first.surveys.new(params)
>> survey.questions.size
=> 1
Rails is duplicating question resource on surveys. Maybe is it a Rails 3.1 bug? The code is similiar to railscasts episode 197.

It was fixed in this commit.
The fix is present Rails 3.1.0rc2, so if you update your Rails version in your Gemfile:
gem 'rails', '3.1.0.rc2'
And run
$ bundle update rails
It should work as expected.

Related

FriendlyId suggest

I want to use FriendlyId to achieve this localhost3000/users/edu/profile but I do not know how to do it!
I have these models User and UserProfile
class User < ActiveRecord::Base
has_one :user_profile, :dependent => :destroy
extend FriendlyId
friendly_id :name, :use => :slugged
end
class UserProfile < ActiveRecord::Base
attr_accessible :user_id, :name, :surname, :nickname
belongs_to :user
end
How do I load in name of User the name of UserProfile? and
How do you update name of User when the name of UserProfile changes?
For the first I used
class User < ActiveRecord::Base
...
def name
if user_profile
"#{user_profile.name}"
end
end
But I can't make it change when I update or create a new Profile in UserProfile.
Using Ruby 1.9.3 and Rails 3.2.13.
If I understood it correctly, your problem is about sharing data between models, not about FriendlyId.
It seems delegate is your best bet here. It's a method in ActiveSupport that allows one model to expose another model's methods as their own.
class User < ActiveRecord::Base
delegate :name, :name=, :to => :user_profile
end
Reference: http://api.rubyonrails.org/classes/Module.html#method-i-delegate
The reason to delegate both :name and :name= is that the former method allows you to read from that attribute (getter), while the latter allows you to write to it (setter).
Before making these changes you'll want to run a migration to remove the name field from the users table in the database, since from now on you'll be using the data in the other model.
rails g migration remove_name_from_users name:string

Setup rails3 text_field for rocket_tag tag list

This is the first time I've tried to add a tags field to a form so bear with me.
I'm using:
rails 3.2.8
Postgres 9.1
rocket_tag 0.5.6
squeel 1.0.9
I have installed the rocket_tag gem and run the various commands
rails generate rocket_tag:migration
rake db:migrate
rake db:test:prepare
to set everything up.
I've amended my Meeting model:
*Adding :tags and :tag_list to attr_accessible
*Adding attr_taggable :tags
*I've added a virtual attribute for displaying the tag list in the form field:
def tag_list
self.tags.join(",")
end
def tag_list=(new_tags)
self.tags = new_tags.split(/,[\s]*/).reject(&:empty?)
end
*I have added f.text_field :tag_list to my form view
This left me with my list page not working though. It said Association named 'taggings' was not found; perhaps you misspelled it?
User
has_many :meetings
has_many :meeting_dates, :through => :meetings
Meeting
belongs_to :user
has_many :meeting_dates
Meeting Dates
belongs_to :meeting
In my list page I list meeting dates using:
user_meeting_dates = #user.meeting_dates.includes(:meeting => :user)
To get past the taggings error I seem to need to have the following in my Meeting Dates model:
has_many :taggings, :through => :meeting
has_many :tags, :through => :taggings
Can someone explain why I need these here and whether there's a way to tidy this up any more, it doesn't seem like it's right.
Should it not be possible to do something like:
user_meeting_dates = #user.meetings.meeting_dates
Thanks
Once I've got this working correctly I can move on to apply Select2 to my tags field but I need to get it working just from a plain text field first.

My has_many model is causing ActiveAdmin to look for a foreign key on the has_on side

I'm new to ruby on rails (and ruby) and I'm trying to get ActiveAdmin working with my model. I've got a lot of the simple stuff working, but ActiveAdmin (on ActiveRecord) is giving me the following error and I cannot figure out why (I'm sure I've misconfigured something, but I don't know what):
Mysql2::Error: Unknown column 'assessment_styles.assessment_definition_id' in 'where clause': SELECT assessment_styles.* FROM assessment_styles WHERE assessment_styles.assessment_definition_id = 1 LIMIT 1
The AssessmentDefinition Model
class AssessmentDefinition < ActiveRecord::Base
attr_accessible :active, :endDOW, :endDate, :isForResearch, :name, :startDOW, :startDa>
has_one :assessmentStyle, :inverse_of => :assessment_definitions
has_one :consentForm
validates :name, :endDOW, :startDOW, :endDate, :startDate, :presence => true
has_and_belongs_to_many :courses
has_and_belongs_to_many :groups
has_and_belongs_to_many :behaviours
end
The AssessmentStyle Model
class AssessmentStyle < ActiveRecord::Base
attr_accessible :name
has_many :assessment_definitions, :inverse_of => :assessmentStyle
end
What am I doing wrong?
Oops! I figured it out (with a little help from Duane's Brain). I was misunderstanding has_one vs. belongs_to, having confused it with the plain English sense of the word and not having realised what it was doing under the hood.

How to give foreign key a name in RoR 3?

How can I give foreign key a name in RoR?
I use following command to give foreign key:
rails generate scaffold Table2 id:integer Table1:references
This command adds foreign key of Table1 in Table2 but with default name that is Table1_id. So how can I give custom name to it for example my_table_f_key instead of Table1_id.
I'm using Ruby 1.9.2 and Rails 3.0.3.
Edit:-
In my project.rb model:
belongs_to :own, :class_name => User
In my user.rb model:
has_many :owned_projects, :class_name => Project, :foreign_key => :owner
how I created my project model
rails generate scaffold Project name:string owner:integer
Now when I access user_id from Project like
project.owner.userid it throws exception.
Based on your responses in the comments, this is one way of implementing what you want to do:
Assuming two models in your app (Users and Questions), and two different relationships:
User asks many Questions, Question belongs_to Asker
User edits many Questions, Question belongs_to Editor
You could implement this structure in the following way:
rails generate scaffold Question asker_id:integer editor_id:integer
Specifying id:integer in your generate command is redundant, as Rails will generate that column for you automatically. It's also conventional to name your foreign keys in terms of the relationship (ie, asker_id).
Then, inside each of your models:
class Question < ActiveRecord::Base
belongs_to :asker, :class_name => User
belongs_to :editor, :class_name => User
end
class User < ActiveRecord::Base
has_many :asked_questions, :class_name => Question, :foreign_key => :asker_id
has_many :edited_questions, :class_name => Question, :foreign_key => :editor_id
end
That way, you can use them together like this:
#question.asker # => User
#question.editor # => User
#user.asked_questions # => [Question, Question, Question]
#user.edited_questions # => [Question, Question]
Hope this helps.
Adding to #Dan's answer, pass the class name as String.
DEPRECATION WARNING: Passing a class to the class_name is deprecated and will raise an ArgumentError in Rails 5.2. It eagerloads more classes than necessary and potentially creates circular dependencies. Please pass the class name as a string
class Question < ActiveRecord::Base
belongs_to :asker, :class_name => User
belongs_to :editor, :class_name => User
end
class User < ActiveRecord::Base
has_many :asked_questions, :class_name => 'Question', :foreign_key => :asker_id
has_many :edited_questions, :class_name => 'Question', :foreign_key => :editor_id
end

Multiple Associations between the same model in Rails

I am working on QA site where I have a Question model and an Answer model and the association between them is like
class Question < ActiveRecord::Base
has_many :answers
end
My answers model is
class Answer < ActiveRecord::Base
belongs_to :question
end
Now I need to create another association between question and answer where I can access the one answer the author of the question finds the best. So what I need is something like
class Question < ActiveRecord::Base
has_many :answers
has_one :accepted_answer, :class_name => 'Answer', :foreign_key => ['answer_id, accepted']
end
This association fails rightly as I have no way of specifying that I expect accepted to be true and I get a MySQL error. Is there a way I can get this to work while using a boolean as composite foreign key?
MySQL server version for the right syntax to use near '["answer_id", "accepted"] = 30) LIMIT 1' at line 1: SELECT `answers`.* FROM `answers` WHERE (`answers`.["answer_id", "accepted"] = 30)
The solution that I have currently employed is creating an association from answers to Question as follows
class Answer < ActiveRecord::Base
belongs_to :question
has_one :inverse_accepted_answer, :class_name => 'Question', :foreign_key => 'accepted_id'
end
and for Question as
Class Question < ActiveRecord::Base
belongs_to :answer, :foreign_key => 'accepted_id'
has_many :answers
end
The problem is in this case i access the selected answer as Question.find(10).answer instead of using a more expressive name as selected_answer.
Is there a way i can define a name for the relationship from the belongs_to end. Secondly what would be the right way to go about this. I technique seems to round about to correct
I am using Rails 3 and Ruby 1.9.2
Thanks in advance
what about something like that:
has_one :accepted_answer, :class_name => 'Answer', :conditions => "accepted = true"