I am having trouble figuring out why rails is showing validation errors. The relevant details of my app are as follows:
Programs are offered in Sessions (many to many) (ProgramSession associates Program and Session)
Courses are offered by Instructors (many to many) (CourseInstructor associates Course and Instructors)
Exams are conducted and each Exam has many Papers.
I have generated all resources using scaffold.
Problem: when I try to create a new paper Rails shows
2 errors prohibited this paper from being saved
- Program session must exist
- Course instructor must exist
Entire code is available on github repo, and has also been deployed on heroku
I would really appreciate all the help I can get.
Making following changes in app/models/paper.rb fixed the problem:
belongs_to :program_session, foreign_key: 'program_sessions_id'
belongs_to :course_instructor, foreign_key: 'course_instructors_id'
check if the value and id of foreign-key is the same as it has set in DB.
and can you provide the controller and model to troubleshoot more
Related
I am new to ruby and rails development and have this question in mind. If i have a concern with scope created say latest_records which gives me latest data for a customer
Now what is the best practice to use scope in this situation. should scopes be in model or in controller?
I read some online articles and it talks about fat model and skinny controller and since scopes are do database related work then i am guessing they should be in model.
Any suggestions or thoughts?
You guessed it right.
Scopes belong to model and needs active record classs object to work on.
Scopes are nothing but a activerecord query divided in parts and it helps look your query elegant and dry.
e.g.
If you want to get users with confirmed emails, you would:
User.where(confirmed: true)
But with scopes in your user model:
scope :confirmed, -> { where(confirmed: true) }
And you would simply:
User.confirmed
For more detailed please refer this answer here
A scope could only be defined in a model so it would have to be on a model.
I'm creating an application based on Devise, CanCan and Rolify to handle private resources.
Devise registration has been disabled since I don't want allow users to registrer, while I'm creating an admin interface to add/edit users.
Now I'm dealing with user role. I'd like to allow admin to create users and set their role using the same form. I don't know what kind of relation is using rolify because I'm pretty new to rails and Ruby and rolify added the rolify method instead of a more clear relation.
I currently need and want to only have one role per user. So if someone edits the user changing the role I delete all #user.roles and then set the new one.
I'm currently having it to work using a simple hack.
I've added a select field to the form, using a collection of Roles to provide a selection of roles. Then inside the create and update methods I'm doing this:
role = params[:user][:role]
params[:user].delete :role
#user = User.new(params[:user])
respond_to do |format|
if #user.save # update_attributes inside update
#user.add_role role
# ...
end
end
As you may see I'm not interacting with the Role model directly but using the provided add_role method. This also creates another issue, because I have to retrieve the current role to allow the update view to set the proper default value for the select (beside the most important fact that I don't know how to validate the presence of ONE role).
This is going to be a too dirt solution, so I'd like to have some point of view, and maybe some suggestion on how to do this. I've spent all the day working on this :-(
If you need some info please ask me.
P.S. I'm watching a screenscast about nested resources but in the DB I may see that it's using a third table to keep track of users_roles and I'm not understanding how to do it.
Thanks!!
At the end I preferred to drop off Rolify.
It was taking too much time for me, and I realized I need a much simpler solution so I'm now using a new column in my model describin the user, and I've also implemented a method similiar to has_role? to keep compatibility with CanCan.
This has solved a lot of problems, and it's a more common solution (= easier help).
In my experience I noticed that if nobody answer your question on SO whithin 30 minutes, then you're doing it too complex.
Thanks everybody.
Is there a way to generate a scaffold for Rails models that have either a has_and_belongs_to_many or has_many :through relationship? If not, is there a developmental reason why some basic form of this functionality has not been included? Rails requires developers to generate and edit a "custom" "join table migration." Is the necessary attention to detail a way of reminding Rails developers of some important fact or is this simply an example of how Rails is a 'work in progress?'
A quick Stackoverflow search for:
"has_and_belongs_to_many" yields 821 questions
"has_many :through" yields 933 questions
... and many of these start with "How do I..." So it seems the topic is not trivial and relevant to SO users. I Guess I am wondering why it has not received attention. Is the matter more complex than it seems? The feature set for Rails seems so extensive. I keep wondering why scaffolding for associations with join tables has been omitted.
Please focus your answer toward the assertions above or "include statement like, "A scaffolding would have to include..." or "A rails generate script would need..."
Thanks!
I like your question, I have wondered for myself why this is not included in Rails (and as I suspect not available as a Gem). Here are some of the reasons why that could be a problem. I will them explain at the typical example with assemblies and parts.
Scaffolding works by using generators to create files. If you migrate to a newer version, there is sometimes the option to update existing files by doing the following steps:
Copy existing ones to a new name.
Overwrite existing ones by new ones.
That implies that there is no notion of adding to files or changing files.
EDIT: This is not true, there are mechanisms to add to files and even change in files.
If you look at the generation of e.g. has_many :through (should be similar to has_and_belongs_to_many) you have to do the following things:
Add a migration that creates the join table.
==> Should be possible for scaffolding by doing: rails g scaffold_hmt Assembly Part
Add a model for that join model.
==> Should be possible for scaffolding by the previous scaffold.
Change existing models to include the lines:
assembly.rb: has_many 'assemblies_parts'; has_many :parts, :through => 'assemblies_parts'
part.rb: has_many 'assemblies_parts'; has_many :assemblies, :through => 'assemblies_parts'
==> So no scaffolding possible
What to do with views is wide open. There are examples at RailsCast how to do it, but it is not at all trivial, and there is no one single technique that works well in all circumstances. I do think that the different patterns could be implemented as templates for scaffolding (e.g. to use checkboxes or multi-select lists or text entry with completion). The problem is the same as in has_many views, however.
So as a summary, a scaffold could be worth a try (see the following paragraph). The RailsGuides to Creating and Customizing Rails Generators & Templates seems plausible at least. And a solution that generates parts of files, names them accordingly and helps in the output of the scaffold on the console to do the rest by hand could be worth a try.
I have tried yesterday to come up with a partial solution, you may have a look at it at GitHub. It works like that:
Copy the contents of the directory scaffold_hmt (stands for has_many :through) to your rails application directory lib/generators.
You may call then the generator with: rails g scaffold_hmt Assembly Part.
It will then generate:
Migration for the join table
Model for the join table
It fails to change the files:
Model assembly.rb
Model part.rb
The reason for that is that the finding of the right place is not trivial. As a workaround, it prints out what should have inserted into the files.
c:\apps\ruby\rails3\minds>rails generate scaffold_hmt Assembly Part
create db/migrate/20111011135944_create_assemblies_parts.rb
create app/models/assemblies_part.rb
Try to insert into file: app/models/assembly.rb the following statements:
has_many :assemblies_parts
has_many :parts, :through => :assemblies_parts
insert app/models/assembly.rb
Try to insert into file: app/models/part.rb the following statements:
has_many :assemblies_parts
has_many :assemblies, :through => :assemblies_parts
insert app/models/part.rb
Give it a try and see if that will help you.
I haven't found a clear explanation for what the association method does and how to use it properly -- I see several examples where model Alpha has_many Beta and then when creating a new Beta using a Factory we say beta.association :alpha or something along those lines. But isn't Alpha also associated with Beta (Beta belongs_to Alpha)... so I'm just pretty confused. I thought an association (at least in normal English) is usually mutual, so I am not understanding what this method is supposed to do. Can someone please clarify this?
In addition to understanding it on a broad conceptual level, I would also like to know exactly what it does on a syntactical level (ie. is it adding methods like attr_accessor does? like what is this actually doing??)
Sorry I just have not found a clear explanation for this -- if anyone can explain this to me that would be great!!
From my experience you define "association" in FactoryGirl when you need to instantiate associated object while creating other object by factory, and without this association your new object would be invalid.
Let's say you have Company and Worker models, and in your application you have validations which prevent creating Worker with invalid company_id attribute. You can have Company without workers (that's why you shouldn't define association for workers in factory), but you can't have Worker without Company. You then add association in factory to lazy-instantiate Company for every Worker created.
So to summarize - you define association when you have belongs_to in model, and when your association in model also have presence validation.
My app has
"normal" users: those which come through a typical signup page
facebook(FB) users: those which come from Facebook connect
"FB-normal" users: a user that can log with both email/password * FB connect
Further, there's the a slew of other openID-ish login methods (I don't think openID itself will be acceptable since it doesn't link up the accounts and allow the 3rd party specific features (posting to twitter, adding a FB post, etc etc))
So, how do I model this?
Right now we have User class with #facebook_user? defined -- but it gets messy with the "FB-normal" users - plus all the validations become very tricky and hard to interpret. Also, there are methods like #deliver_password_reset! which make no sense in the context for facebook-only users. (this is lame)
I've thought out STI (User::Facebook, User::Normal, User::FBNormal, etc.) This makes validations super slick, but it doesn't scale to other connection types, and all the permutations between them... User::FacebookLinkedInNormal(wtf?) Doing this with a bunch of modules I think would suck a lot.
Any other ideas?
I would split up the concerns, seems like it doesn't make sense to keep records that have vastly different fields in one table.
Just have one User model/table that doesn't save any credentials, and make that have a has_many relationship to an Account/Login Method, where you could use STI to model the different types.
class User < AR::B
has_many :accounts
end
class Account < AR::B;end
class PasswordAccount < Account;end
class GoogleAccount < Account;end
class FacebookAccount < Account;end
…
You're running into one of those object-relational impedance mismatch landmines.
Facebook and LinkedIn each solve this by using non-relational key/value stores. Facebook uses Cassandra, and LinkedIn uses Project Voldemort.
When you're not bound by the conventions of the relational model (e.g. all rows of a given table have the same columns), you can gain more flexibility and vary the attributes per row. But doing this, you sacrifice some strengths of the relational model (e.g. all rows of a given table have the same columns).
In an RDBMS, I would architect this using Class Table Inheritance.