Rails association - difficulty getting form_for to work - ruby-on-rails-3

I have a Member model that belongs to User
class Member < ActiveRecord::Base
attr_accessible :name
belongs_to :user
end
class User < ActiveRecord::Base
attr_accessible :name
has_many :members, :dependent => :destroy
end
In my Members controller I have
class MembersController < ApplicationController
def create
#user = User.find(params[:user_id])
#member = #user.members.build(params[:member])
if #member.save
flash[:success] = "Member created!"
redirect_to root_path
else
render 'pages/home'
end
end
end
In /app/views/users/show.html.erb I have
<%= form_for #member do |f| %>
<div class="field">
<%= f.text_area :name %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
But I get the following error:
undefined method `model_name' for NilClass:Class
Extracted source (around line #18):
15:
16: <h1 class="member">What's up?</h1>
17:
18: <%= form_for #member do |f| %>
My show action in the Users controller is
def show
#user = User.find(params[:id])
#members = Member.new
#title = #user.name
end
Which also contains the 'new' method
I have tried changing :user_id to :id in the MembersController but this does not work either. What am I doing wrong here?
thanks in advance

Try to replace #members = Member.new by #member = Member.new ;-) !

I needed to pass the #user.id as a hidden field in the form, for the association to work!

Related

How do I capture select value from dropdown menu in rails?

I have cities table and profiles table. Below is the models of both:
class City < ActiveRecord::Base
belongs_to :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
has_one :city
end
I am trying to create a dropdown list for cities in profile view page.
<%= form_for #profile, url: user_profile_path, :html => { :multipart => true} do |f| %>
<div class="field">
<%= f.label :country %>
<%= f.text_field :country %>
</div>
<div class="field">
<%= f.label :city_id %>
<%= f.select :city_id, options_for_select(#city.collect{ |u| [u.name, u.id] }) %>
</div>
<div class="actions">
<%= f.submit "Update Profile" %>
</div>
<% end %>
Here is the ProfilesController:
class ProfilesController < ApplicationController
def new
#user = User.find( params[:user_id] )
#profile = Profile.new
#city = City.all
end
def create
#user = User.find( params[:user_id] )
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile Updated!"
redirect_to user_path( params[:user_id] )
else
render action: :new
end
end
end
How do I add city_id column in the profiles table, I am unable to capture city_id from the above ProfilesController.
I tried to #city = City.find( params[:city_id] ) in "ProfilesController",
"Def create", and I got this error:
Couldn't find City with 'id'=
Please advice.
Maybe try to replace
has_one :city
by
belongs_to :city
in your profile model and in your city model replace
belongs_to :profile
by
has_many :profiles
try whitelisting city_id instead of city
private def profile_params
params.require(:profile).permit(:country, :city)
end
Change you associations-
class City < ActiveRecord::Base
has_one :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
belongs_to :city
end
city_id column should be in that model where you are using belongs_to association

Rails - Nested Model Fails to Save

I'm rather new to Rails and I'm writing a signup form that includes nested models. When I submit the form, the user is saved just fine, but the nested model does not save anything to the Subscription db, and the console throws no errors.
I sincerely hope I'm not missing something insanely obvious, and I appreciate any tips you can share. Thanks!
Here is the code-
Models:
class Plan < ActiveRecord::Base
attr_accessible :posts, :name, :price
has_many :users
end
class User < ActiveRecord::Base
belongs_to :plan
has_many :events
has_one :subscription, :autosave => true
accepts_nested_attributes_for :subscription
attr_accessible :subscription_attributes
def save_with_payment
if valid?
customer = Stripe::Customer.create(
email:email,
plan: plan_id,
card: stripe_card_token )
self.stripe_customer_token = customer.id
save!
end
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error while creating customer: #{e.message}"
errors.add :base, "There was a problem with your credit card."
false
end
end
class Subscription < ActiveRecord::Base
attr_accessible :plan_id, :status, :user_id
belongs_to :user
end
This is the User controller:
def new
#user = User.new
plan = Plan.find(params[:plan_id])
#user = plan.user
#user.build_subscription
end
def create
#user = User.new(params[:user])
if #user.save_with_payment
sign_in #user
flash[:success] = "Welcome to the SendEvent!"
redirect_to #user
else
render 'new'
end
end
This is the form:
<%= form_for #user, :html => {:class => "form-inline"} do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="control-group">
<%= f.label :name, :class => "control-label" %>
<%= f.text_field :name %>
</div>
# A few more fields here and...
# The nested model:
<%= f.fields_for :subscription do |builder| %>
<%= builder.hidden_field :status, :value => true %>
<% end %>
<%= f.submit "Create my account", class: "btn btn-large btn-primary", id: "submitacct" %>
<% end %>
Sample app from RailsCasts
RailsCasts Episode #196: Nested Model Form (revised)
Maybe help you.

creating a join action between user and group correctly

I have a problem when trying to create a membership for users based on the name they input into the membership form - new.html.erb.
user.rb
has_many :memberships, :dependent => :destroy
has_many :groups, :through => :memberships
membership.rb
class Membership < ActiveRecord::Base
attr_accessible :user_id, :group_id
belongs_to :user
belongs_to :group
end
group.rb
has_many :memberships, :dependent => :destroy
has_many :users, :through => :memberships
membership controller
def create
#group = Group.find_by_name(:group)
#membership = current_user.memberships.build(:group_id => #group.group_id)
if #membership.save
flash[:notice] = "You have joined this group."
redirect_to :back
else
flash[:error] = "Unable to join."
redirect_to :back
end
end
membership - _form.html.erb
<%= form_for(#membership) do |f| %>
...
#error validation
...
<div class="field">
<%= f.label :group %><br />
<%= f.text_field :group %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
What I want it to do is find the group inputted if it exists, and create the table entry in the memberships table accordingly. Just not sure if what I'm doing is on the right track. Any suggestions?
The reason your code isn't working now is because of this line:
#group = Group.find_by_name(:group)
it should be something like (I don't remember exactly sorry)
#group = Group.find_by_name(params[:membership][:group])
The error is getting called on the next line because #group is nil.
But you should probably handle that type of logic in the model anyway with a virtual attribute or something.
membership.rb
def group_name
if self.group
#group_name ||= self.group.name
end
end
def group_name=(group_name)
#group_name = group_name
self.group = Group.find_by_name(#group_name)
end
form
<div class="field">
<%= f.label :group_name, "Group" %><br />
<%= f.text_field :group_name %>
</div>
controller
def create
#membership = current_user.memberships.build(params[:membership])
if #membership.save
flash[:notice] = "You have joined this group."
redirect_to :back
else
flash[:error] = "Unable to join."
redirect_to :back
end
end

Rails3 routing error

My scenario: Movies have reviews, reviews have comments.
Movie model:
has_many :reviews
Review model:
has_many :comments
belongs_to :movie
Comment model:
belongs_to :review
Routes:
resources :movies do
resources :reviews do
resources :comments
end
end
Comments controller:
def create
#movie = Movie.find(params[:movie_id])
#review = Review.where(:movie_id => #movie.id)
#comment = #review.comments.create(params[:comment]) // Line 5
redirect_to movie_path(#movie)
end
Comment view:
<%= form_for([#movie, r, r.comments.build]) do |f| %>
<div class="field">
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit "Submit" %>
</div>
<% end %>
The error that I get is:
NoMethodError (undefined method `comments' for #<ActiveRecord::Relation:0x007ff5c5870010>):
app/controllers/comments_controller.rb:5:in `create'
Can somebody please tell me what I'm doing wrong?
Thanks in advance..
Review.where returns a list of reviews, what you want is an instance
#review = Review.where(:movie_id => #movie.id).first
or
#review = Review.find_by_movie_id(#movie.id)
Make sure to handle nil case.

how to insert same data into two tables using nested forms

I am using nested forms to insert data into two tables (user and address).I want to have my users email id in both the table, but the user should enter the email id once. Here is my current view
<%= form_for #user do |f| %>
<%= f.text_field(:name, :size => 20) %>
<%= f.text_field(:email, :size => 20) %>
<%= f.fields_for :address do |r| %>
<%= r.text_field(:street, :size => 20) %>
<%= r.text_field(:city, :size => 20) %>
<% end %>
<%= f.submit "Create" %>
<% end %>
In my nested section "address" i once again want the email field, but i don't want a repeated text field for email. How can i use the email section inside the nested form "address"? I have tried using hidden form fields, but it didn't worked. Can somebody help please.
EDIT
Controller(Only question related parts)
class UsersController < ApplicationController
def new
#domain = Domain.find(params[:id])
#user = #domain.users.build
#title = "Add User"
end
def create
#user = User.new(params[:user])
if #user.save
flash[:success] = "Welcome!"
redirect_to manageDomain2_path(:id => #user.domain_id)
else
#title = "Add User"
redirect_to addNewUser_path(:id => #user.domain_id)
end
end
I have tried with:
#user = User.new(params[:user][:address_attributes].merge!(:email => params[:user][:email]))
When using:
#user = User.new(params[:user][:address].merge!(:email => params[:user][:email]))
I am getting error "Undefined method merge".
User Model (Question related portion only)
class User < ActiveRecord::Base
attr_accessible: :email, :domain_id, :address_attributes
belongs_to :domain
has_one :address
accepts_nested_attributes_for :address
end
Address Model (Full)
class Address < ActiveRecord::Base
attr_accessible :user_id, :email, :street, :city
end
When i use
belongs_to :user
in address model i get syntax error. So i have tried without using it. the user_id, street, city is getting proper values but email email field is not getting any thing.
You can just add it to the params hash from your controller:
params[:user][:address].merge!(:email => params[:user][:email])