assign child to one of parents in rails form - ruby-on-rails-3

I have problem how to create form for assigning child to one of parents. My child-nodes are defined in system, i go to child (alias) and want to assign it to one of parents contacts) (or create new). How do I create such form?
class Alias < ActiveRecord::Base
belongs_to :user
belongs_to :contact
end
class Contact < ActiveRecord::Base
has_many :aliases
belongs_to :user
end
So i have couple objects of Alias and couple of Contact, but I don't want to go to Contact and there assign Alias, but go to Alias, and pickup one of Contacts from (example) select box.

There are many ways to select the association id. A select box is probably the most space efficient on a page, but sometimes radio buttons work nice if there are few possible associations.
I think something like this might suit you. This assumes you assign #contacts to something like Contact.all inside your controller.
= form_for #alias do |f|
= f.label :contact_id, "Contact"
= f.collection_select :contact_id, #contacts, :id, :full_names
This assumes you have a field called "full_names" in your contact. Put whatever field you want to show in the select box.
Creating the Contact from the Alias is more tricky, and personally I wouldn't recommend it. Here are a couple questions which explain how to do it though:
Does accepts_nested_attributes_for work with belongs_to?
Getting fields_for and accepts_nested_attributes_for to work with a belongs_to relationship
I hope that helps.

Related

Is there a way to show an enum from another model into a select picker?

I'm a little bit new to Ror. I have a relation one to one between a model 'VotationType' and 'Question'. This relation have to be polymorphical. Now i need a way that allows me to show a select picker in the question/new.html.erb that in the dropdown lists the enum_types for selecting one of them.
Model votation_type.rb
class VotationType < ApplicationRecord
belongs_to :questionable, polymorphic: true
enum enum_type: %i[unique prioritized open_positive answer_couple answer_set]
Model quiestion.rb:
class Question < ApplicationRecord
has_one :votation_type, as: :questionable
The main problem of this is that i can figure it out how can i list the enum_type in the view from another model.
Found a method that works for the moment:
<%= f.select :votation_type, options_for_select(VotationType.enum_types) %>

Adding a column Migration with a default value in ruby on rails

I am using SQLite3 and I would like the following to work:
class AddNameToGoal < ActiveRecord::Migration
def change
add_column :goals, :goal_name, :text, default: goal.exercise.name
end
end
Or maybe this makes more sense as what I'm trying to do:
add_column :goals, :gname, :text, default: Goal.find(row_id).exercise.name
How do I get the above to work.
I doubt it will work as it is but that's what I want.
Specifically, The user is associated with an Exercise through the exercise_id column.
belongs_to :user
belongs_to :exercise
has_many :workouts, dependent: :destroy
(This is the model for Goal)...
I would like the user to be able to choose their own name for the Goal but I can give them the hint to name the goal after the Exercise's name and if they choose to leave it blank it will default to the exercise's name. More importantly this must happen on the SQL side so that later when I have a collection drop down which requires a name of the goal they will need a name which corresponds to the exercise.
<%= f.collection_select(:goal_id, #goals, :id,
:goal_name, :include_blank => "Please Select") %>
The Exercise Model is made in Rails to have
id, Name, other columns.
Exercise Model:
class Exercise < ActiveRecord::Base
has_one :goal
Is there a strategy by which that is possible.
Another option would be to help me find a strategy for active record so that I can do:
<%= f.collection_select(:goal_id, #goals, :id,
:goal_name, :include_blank => "Please Select") %>
with (something else to replace goal_name with Exercise.name like goal.exercise.name and goal.id and show only the ID.
Doing this when you define the column on the table is problematic. I definitely think doing it upon creation, in the model, is how you'd want to go.
You might also check out the default_value_for gem and see if it helps.
Hi so in case any body ever wants to do this:
I figured out a strategy...
This is perfect for anything that has an instance of name in terms of the user.
For example, you have something that tracks your Car and you want to give that Car by default the name which comes from that Car's Make_and_Model (model) in Rails.
Naturally when someone says they have a new "Honda Accord" then they get to have that name, but if they ever want to change it to "Lucy" because her name is Lucy and you better treat her with the respect she deserves!, then this gives you the option to do that.
You do not want to change the name for that whole Make&Model you only want to change the name for that specific car.make_and_model which belongs_to User.
If you are wanting something to have a name that defaults to another name but allows the user to change that. Do that on the model level... by setting a before_save method inside the model... like so:
before_save :default_values
def default_values
self.goal_name = self.exercise.name if self.goal_name.nil?
end

How to implement has_many :through relationship in rails with this example

i've been searching through similar questions but i still don't get how implement this relationship. I have of course three models :
class Recetum < ActiveRecord::Base
attr_accessible :name, :desc, :duration, :prep, :photo, :topic_id
has_many :manifests
has_many :ingredients, :through => :manifests
end
class Ingredient < ActiveRecord::Base
attr_accessible :kcal, :name, :use, :unity
has_many :manifests
has_many :recetum, :through => :manifests
end
class Manifest < ActiveRecord::Base
attr_accessible :ingredient_id, :quantity, :receta_id
belongs_to :recetum
accepts_nested_attributes_for :ingredient
belongs_to :ingredient
end
Recetum would be a recipe (typo when scaffolding), this recipe may have one or more ingredients (already on the db). So when i create a new Recetum, i need the new recetum to be created and one record inserted in manifest for each ingredient entered by the user.
I would need some help now with views and controllers, how do i create the form for recetum with fields for the ingredients and more important what do i have to modify recetum controller.
Any suggestions or help would be very much appreciated as this part is crucial for my project, thanks in advance.
You have a couple options, and mainly they depend on what you want to do in your view. Do you want to display a set number of max_ingredients or do you want it to be completely dynamic? The dynamic case looks better for the user for sure, but it does make for some more complicated code.
Here is a good RailsCast which explains how to do it dynamically via JavaScript:
http://railscasts.com/episodes/74-complex-forms-part-2
Unfortunately, not everyone runs with JavaScript enabled so you may want to consider doing it the static way.
Firstly, I don't think you need accepts_nested_attributes_for in your Manifest model. However, I do think you need it in your Recetum model. If you're going the static route, you'll probably want to set a reject_if option too.
accepts_nested_attributes_for :manifests, reject_if: :all_blank
Once you do this, you'll need to add manifests_attributes to your attr_accessible.
With the static route, you'll need to prebuild some of the manifests. In your new controller you'll want something like this:
max_ingredients.times do
#recetum.manifests.build
end
In your edit and the error paths of your create and update, you may want:
(max_ingredients - #recetum.manifests.count).times do
#recetum.manifests.build
end
Finally, your view will need some way to set the ingredient. I'll assume a select box for now.
f.fields_for :manifests do |mf|
mf.label :ingredient_id, "Ingredient"
mf.collection_select :ingredient_id, Ingredient.all, :id, :name
You'll want to add some sort of formatting through a list or table probably.
Hopefully, that's enough to get you started.

Rails adding resource id to another resource via HABTM

I have 3 pertinent models:
class User < ActiveRecord::Base
has_and_belongs_to_many :groups
end
class Group < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :galleries
end
class Gallery < ActiveRecord::Base
belongs_to :group
end
I want to be able to create users and galleries within a group so that only users who are members of the group can view the galleries that belong to that group. I also want users to be able to view galleries of other groups they belong to (hence the HABTM association).
I'm having difficulty in conceptualizing how this works with controllers, and perhaps I'm over thinking the problem. If I create a Group, and then I go to create a user, what is the best way to go about adding the current group_id to the user model? Same thing goes for the gallery model...
Does that make sense?
Let me know if I need to clarify or add code samples.
Thank you very much for your help.
EDIT: Clarification
I definitely didn't make any sense in my initial question, but I did manage to find the answer, with help from a friend.
What I ended up doing is passing the group_id to the form via the params hash like so:
<%= link_to "Add User", new_admin_user_path(:group_id => #group.id) %>
<%= link_to "Add Gallery", new_gallery_path(:group_id => #group.id) %>
Then using a hidden field in my form, assigning the group_id to the "group_id" hidden field:
<%= hidden_field_tag :group_id, params[:group_id] %>
And, finally, in my create methods, adding these lines before the save assigns the group_id perfectly:
# Gallery only has one group
#gallery.group_id = params[:group_id]
# Users can belong to many groups
#user.groups << Group.find(params[:group_id])
I'll still need to sit down and wrap my head around the answers you both provided. Thank you very much for taking the time to help me out. I really appreciate it.
When you are using find method from your controller you can make it like this:
Gallery.find :all, :joins => "INNER JOIN groups ON groups.gallery_id = galleries.id INNER JOIN users ON users.group_id = groups.id", :conditions => "users.id = #{#your_current_user_id}"
It must find all galleries of groups which the user belongs.
I would not define this in the controller as Sebes suggests, but rather in the User model.
Adapting his idea:
def galleries
Gallery.joins(:groups => :users).where("users.id = ?", self.id)
end
Then to get a collection of the galleries for the current_user object:
current_user.galleries

Multi Model Form in Rails 3

I'm still a bit of a n00b when it comes to rails, however, I do have a question as to how to go about a multi-model form.
Basically, I have an event, and the user needs to be able to register for the event and provide a credit card for charging the event to. The credit card (I won't be holding the actual data for the CC, authorize.net will, but I need to keep a token representing the card) will live with the user so they can sign up for other events in the future. So, I want the user to be able to edit this in the future, and the card isn't specific to a single event. This doesn't seem like something I'd use nested routes with, does it?
I have a feeling this is fairly simple, but I guess I'm just not entirely sure how to do it. Can I used nested models (not routes) and still update each portion independently?
If I understand your question, then yes you can. I think you mean something like this:
class User < ActiveRecord::Base
has_one :credit_card
end
If that's correct, then the first step is to add this to the User class:
class User < ActiveRecord::Base
has_one :credit_card
accepts_nested_attributes_for :credit_card
end
At this point you could just set up a "users" resource in the routes file and you could edit the credit card through a fields_for method in your edit view:
form_for #user do |f|
f.fields_for :credit_card do |ff|
ff.label :number
ff.text_field :number
end
f.submit
end
Does that help?
Since Formatting is not allowed in comments, I am making a answer for it.
Thanks #twmills for your answer,
I am also new to rails. I have a question, will it work in case where I have following relationship:
class User < ActiveRecord::Base
has_many :credit_cards, :dependent => :destroy
accepts_nested_attributes_for :credit_card
end
class CreditCards < ActiveRecord::Base
belongs_to :user
end
In above case, you can't create a CreditCard object unless you have parent user. Will f.fields_for :credit_card do |ff| also create an object of CraeditCard #user to f?
As per my understanding, this is not possible as how will be tell the view, which credit card to edit.
Secondly, On edit, this is fine but can I do something similar at the time of user creation. i.e. getting his credit card information at the time of user creation.