setting user alias as message recipient - ruby-on-rails

I have two models, user and treating (which you can think of as a message).
User:
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
has_many :sent_treatings, :foreign_key => "requestor_id", :class_name => "Treating", dependent: :destroy
has_many :received_treatings, :foreign_key => "requestee_id", :class_name => "Treating", dependent: :destroy
end
Treating:
class Treating < ActiveRecord::Base
attr_accessible :intro, :proposed_date, :proposed_location
validates :intro, presence: true, length: { maximum: 190 }
validates :requestor_id, presence: true
validates :requestee_id, presence: true
belongs_to :requestor, class_name: "User"
belongs_to :requestee, class_name: "User"
default_scope order: 'treatings.created_at DESC'
end
I'm having trouble in my treatings controller setting 'requestee':
class TreatingsController < ApplicationController
before_filter :signed_in_user
def create
requestee = ?
requestor = current_user
#received_treating = requestee.received_treatings.build(params[:treating])
#received_treating.requestor = requestor
if #received_treating.save
flash[:success] = "Treating request sent!"
redirect_to users_path
else
render 'static_pages/home'
end
end
end
The question mark I tried to replace with: User.find(params[:id]), hoping that the user in the current 'users/show' view would be found, but I get this error:
Couldn't find User without an ID
I also tried User.find(params[:treating][:requestee_id]), but this didn't work either. Any ideas?
Thanks!
EDIT:
views/shared/_treating_form.html.erb (this references #received_treating in the users controller, show action):
<div class="field">
<%= f.text_area :intro, placeholder: "Write your introduction here..." %>
</div>
<%= f.submit "Send", class: "btn btn-large btn-primary" %>
EDIT: adding other user profile page:
<% provide(:title, #user.name) %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</section>
<% if signed_in? %>
<section>
<%= render 'shared/treating_form' %>
</section>
<% end %>
</aside>
<div class="span8">
<% if #user.received_treatings.any? %>
<h3>Treating requests (<%= #user.received_treatings.count %> received)</h3>
<ol class="treatings">
<%= render #received_treatings %>
</ol>
<%= will_paginate #received_treatings %>
<% end %>
</div>
</div>

I think just adding #user.id in a hidden_field would work.
<%= f.hidden_field :requestee_id, :input_html => { :value => #user.id }
<div class="field">
<%= f.text_area :intro, placeholder: "Write your introduction here..." %>
</div>
<%= f.submit "Send", class: "btn btn-large btn-primary" %>
You could also populate the field doing
<%= form_for #user.received_treatings.build do %>
<%= f.hidden_field :requestee_id %>
....
On the controller just do
#received_treating = current_user.sent_treatings.build params[:treating]
I have some doubts if this works but I think it should help you out.

Related

Rails nested attribute not saving

In my models I have
class Blog < ActiveRecord::Base
has_many :tags, :dependent => :destroy
accepts_nested_attributes_for :tags, :allow_destroy => true
end
class Tag < ActiveRecord::Base
belongs_to :blog
validates :blog, :name, presence: true
end
Blog Controller
def new
#blog = Blog.new
#blog.tags.build
end
_form.html.erb
<%= form_for #blog, html: { multipart: true } do |f| %>
<div class="form-group">
<%= f.text_field :title, placeholder: 'Title', class: ('form-control') %>
</div><br>
<%= f.fields_for :tags do |builder| %>
<div class="form-group">
<%= builder.text_field :name, placeholder: 'Tags' %>
</div><br>
<% end %>
<div class="actions text-center">
<%= f.submit 'Submit', class: 'btn btn-primary' %>
</div>
<% end %>
Blog Controller
def create
#blog = Blog.new(blog_params)
binding.pry
end
def blog_params
params.require(:blog).permit(:title, :author, :text, :avatar, :banner, :tags_attributes => [:id, :name])
end
At my binding, it says #blog's error message is that it can't be saved because the Tag object is missing a blog_id. I have looked everywhere and I have tried to replicate my code to match other solutions but to no success.
If it helps, in my params when I submit the form I get this
"tags_attributes"=>{"0"=>{"name"=>"dsfsf"}}
that's because your #blog is not persisted in the db yet, so you won't have the id.
In your Tag model, remove :id from validation.
You should be able to just do Blog.create(blog_params)
Rails should handle the rest for you.

ActionController::InvalidAuthenticityToken When Submitting

I have a program that allows users to enter their song for a certain event. You must enter in the partycode for that event in order for it to submit. Here is a screenshot of what it looks like:
When I submit it gives me this error:
Here is what my SongsController looks like:
class SongsController < ApplicationController
def new
#song = Song.new
end
def create
current_event = Event.find(song_params[:event_id])
#song = current_event.songs.build(song_params)
if #song.save
flash[:success] = "Success"
redirect_to event_path(#song.event)
else
flash[:error] = "Failed"
end
end
def destroy
end
private
def song_params
params.require(:song).permit(:event_id, :artist, :title, :genre)
end
end
event model
class Event < ApplicationRecord
belongs_to :user
validates :name, presence: true
validates :partycode, presence: true, length: {minimum: 5}
has_many :songs, dependent: :destroy
end
song model
class Song < ApplicationRecord
belongs_to :event
validates :artist, presence: true
validates :title, presence: true
end
new.html.erb(song)
<br>
<br>
<h1> Member page </h1>
<div class ="container">
<div class="jumbotron">
<h2> Select an event to add songs to: </h2>
<%= form_for Song.new do |f| %>
<%= f.collection_select(:event_id, Event.all, :id, :name) %>
<h3> Enter your song </h3>
<%= form_for Song.new do |f| %>
<%= f.text_field :artist, placeholder: "Artist" %>
<%= f.text_field :title, placeholder: "Title" %>
<%= f.text_field :genre, placeholder: "Genre" %>
<h2> Enter the partycode for that event: </h2>
<%= form_for Event.new do |f| %>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
<% end %>
<% end %>
</div>
</div>
What can I do to make this functionality of my website work? Any help is greatly appreciated thanks
I see many form_for nesting on your views. It's impossible. Only one submit for a form.
I think you may want to change your _form.html.erb
<div class ="container">
<div class="jumbotron">
<h2> Select an event to add songs to: </h2>
<%= form_for #song do |f| %>
<%= f.collection_select(:event_id, Event.all, :id, :name) %>
<h3> Enter your song </h3>
<%= f.text_field :artist, placeholder: "Artist" %>
<%= f.text_field :title, placeholder: "Title" %>
<%= f.text_field :genre, placeholder: "Genre" %>
<h2> Enter the partycode for that event: </h2>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
</div>
</div>
You have completely messed up your form. Ideally you should have one form but here you have just kept one form within another form using form_for.
I would recommend you to have a look at the form_for documentation .

Validation failed: Stocks product must exist, Stocks location must exist

I have three models -> locations, products and stocks.
Stocks is a join table of locations and products.
When creating a new product i used fields_for to show locations and even though i got it to work, for some reason now it does not seem to work anymore and it gives me the above error.
<div class="input-field">
<%= f.label :product_name %>
<%= f.text_field :name, autofocus: true %>
</div>
<div class="input-field">
<%= f.label :price %>
<%= f.text_field :price, autofocus: true %>
</div>
<% if !#edit %>
<%= f.fields_for :stocks do |ff| %>
<div class="input-field margin-top x-4">
<%= ff.collection_select :location_id, Location.all, :id, :structured_location , {:prompt => "Please Select Locations for Product"}, {multiple: true} %>
<%= ff.label :locations %>
</div>
<div class="input-field">
<%= ff.label :quantity %>
<%= ff.text_field :quantity %>
</div>
<div class="input-field">
<%= ff.label :threshold_quantity %>
<%= ff.text_field :threshold_quantity %>
</div>
<% end %>
<% else %>
<%= collection_select :product, :location_ids, Location.all, :id, :structured_location , {:prompt => "Please Select Locations for Product"}, {multiple: true} %>
<% end %>
<div class="row margin-top x-4">
<div class="col s12 center-align">
<%= f.submit "#{current_page?(new_product_path) ? "Create Product" : "Update Product"}", class: "btn wave-effect pink darken-1 btn-large" %>
</div>
</div>
controller
class ProductsController < ApplicationController
helper_method :sort_column, :sort_direction
def index
#products = Product.order(sort_column + " " + sort_direction)
end
def new
#product = Product.new
#product.stocks.build
end
def create
#product = Product.new(product_params)
if #product.save!
flash[:notice] = "Successfully saved..."
redirect_to products_path
else
flash[:alert] = "Something went wrong, please check the values you entered"
redirect_to :back
end
end
private
def product_params
params.require(:product).permit(:name,:price, location_ids: [], stocks_attributes: [:id, :quantity, :threshold_quantity, location_id: []])
end
end
product model
class Product < ApplicationRecord
has_many :stocks, dependent: :destroy
has_many :locations, :through => :stocks
accepts_nested_attributes_for :stocks
end
parameters in rails console
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"l1BFhrdyB2QMO5k3+60GNiPphFfF+DXDGPbUU3V2Op2aekObjgIe13k8uoedmDIEZgIeXPZUeS/0VxQXkKa1Uw==",
"product"=>{"name"=>"Soap", "price"=>"10", "location_ids"=>["", "1",
"2"], "stocks_attributes"=>{"0"=>{"quantity"=>"100",
"threshold_quantity"=>"100"}}}, "commit"=>"Create Product"}
After hours of searching i stumbled upon this post
BigBinary
it seems that Rails 5 made belongs_to relationship IDs required by default thats why i had validations failed and i couldn't find anything about it.
simply adding optional: true in my stock model worked!
class Stock < ApplicationRecord
belongs_to :location, optional: true
belongs_to :product, optional: true
accepts_nested_attributes_for :product, allow_destroy: true
accepts_nested_attributes_for :location, allow_destroy: true
end

How can I avoid ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection errors in my setup?

I have the following models in my rails app:
class SaleContact < ActiveRecord::Base
validates :key_contact_id, presence: true, uniqueness: { scope: :sales_opportunity_id, message: "Contact already added!" }
validates :sales_opportunity_id, presence: true
belongs_to :key_contact, inverse_of: :sale_contacts
belongs_to :sales_opportunity, inverse_of: :sale_contacts
has_many :phone_numbers, :through => :key_contact
accepts_nested_attributes_for :phone_numbers
end
I'm trying to create a sale_contact from the sales_opportunity screen by selecting a key_contact (assume a key_contact already exists). I would also like the ability to add a phone_number at the same time using fields_for and nested attributes.
class KeyContact < ActiveRecord::Base
validates :first_name, :last_name, :company_id, presence: true
has_many :phone_numbers, dependent: :destroy
belongs_to :company
has_many :sales_opportunities, :through => :sale_contacts
has_many :sale_contacts, dependent: :destroy
end
Assume I've already created the key_contact and assigned it to the company that owns it.
class PhoneNumber < ActiveRecord::Base
validates :number, :key_contact_id, presence: true
belongs_to :key_contact
end
Nothing magical here - just a very basic model for a phone number.
On the sales_opportunity page I can load a modal that adds a new sale_contact. It's a bootstrap modal loaded by AJAX, but I don't think that matters much (I've only included the form parts for brevity):
<%= form_for(#sale_contact, :html => {role: :form, 'data-model' => 'sale_contact'}, remote: true) do |f| %>
<% if #sale_contact.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#sale_contact.errors.count, "error") %> prohibited this sale_contact from being saved:</h2>
<ul>
<% #sale_contact.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group" id= "contact_error">
<%= f.label :key_contact_id, :class => "control-label" %>
<div id="contact_select">
<%= f.collection_select :key_contact_id, #sales_opportunity.company.key_contacts(:full_name), :id, :full_name %>
</div>
<span class="warning-block"></span>
<span class="help-block"></span>
</div>
<div class="form-group">
<%= f.label :role, :class => "control-label" %>
</br>
<%= f.select(:role, options_for_select(#roles.collect { |r| [r[0].humanize, r[0]] }, selected: #sale_contact.role), {}) %>
<span class="help-block"></span>
</div>
<div class="form-group">
<%= f.label :preference, :class => "control-label" %>
</br>
<%= f.select(:preference, options_for_select(#preferences.collect { |r| [r[0].humanize, r[0]] }, selected: #sale_contact.preference), {}) %>
<span class="help-block"></span>
</div>
<%= f.fields_for(:phone_numbers) do |phone| %>
<div class="form-group">
<%= phone.label :number, "Phone Number", :class => "control-label" %>
</br>
<%= phone.text_field :number, :placeholder => "Enter phone number (optional)" %>
<span class="help-block"></span>
</div>
<div>
<%= phone.hidden_field :key_contact_id %>
</div>
<% end %>
<div class="form-group">
<%= f.hidden_field :sales_opportunity_id, :value => #sales_opportunity.id %>
</div>
<%= f.submit "Save", class: "btn btn-large btn-success", data: { disable_with: "Submitting..." }%>
<% end %>
And from my sale_contact_controller new action:
def new
#sale_contact = SaleContact.new
#sale_contact.phone_numbers.build
#sales_opportunity = SalesOpportunity.find(params[:sales_opportunity_id])
#company = #sales_opportunity.company
#roles = SaleContact.roles
#preferences = SaleContact.preferences
render :modal_form
end
def sale_contact_params
params.require(:sale_contact).permit(:key_contact_id, :sales_opportunity_id, :role, :preference, phone_numbers_attributes: [:number, :id])
end
I run a javascript snippet when the modal is being retrieved via AJAX or the key_contact select dropdown changes to bring in the key_contact_id to the phone_numbers_attributes; if I don't do that I get a 422 unprocessable entity error for not sending through my key_contact_id.
Using this setup the modal pops into view and has the correct fields (both for sale_contact and phone_number), but will not save either of these models - I get a 500 error:
Completed 500 Internal Server Error in 17ms
ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection (Cannot modify association 'SaleContact#phone_numbers' because the source reflection class 'PhoneNumber' is associated to 'KeyContact' via :has_many.):
app/controllers/sale_contacts_controller.rb:50:in `block in create'
app/controllers/sale_contacts_controller.rb:49:in `create'
I've tried other methods, such as setting the key_contact_id in the sale_contact create method, but I get the same result. I can't work out why this setup complains when I don't pass a key_contact_id (422 error) and complains when I do (500 internal server error as the key_contact_id is being set internally by the rails associations).
What does Rails want me to do here?
I had a similar issue with my form, but I was able to get passed it by using nested field_for tags
Proposal.rb
has_many :proposal_section_reviews, :through => :proposal_review_status
has_one :proposal_review_status, :dependent => :destroy
attr_accessible :proposal_review_status_attributes, :proposal_review_status_attributes, :proposal_section_reviews_attributes
accepts_nested_attributes_for :proposal_review_status, :proposal_section_reviews
ProposalSectionReview.rb
belongs_to :proposal_review_status
ProposalReviewStatus.rb
has_many :proposal_section_reviews, :dependent => :destroy
_form.html.haml
= form_for proposal do |f|
= f.fields_for :proposal_review_status do |ff|
= ff.fields_for :proposal_section_reviews
So in your instance I would try
<%= f.fields_for(:key_contact) do |key| %>
<%= key.fields_for(:phone_numbers) do |phone| %>
<div class="form-group">
<%= phone.label :number, "Phone Number", :class => "control-label" %>
</br>
<%= phone.text_field :number, :placeholder => "Enter phone number (optional)" %>
<span class="help-block"></span>
</div>
<div>
<%= phone.hidden_field :key_contact_id %>
</div>
<% end %>
<% end %>
Hope this helps

Create 2 Models at the same time

Ok I've searched far and wide and can't find a solution that I can get working...so I decided to post here.
I have 2 models
Store
class Store < ActiveRecord::Base
attr_accessible :storeimage, :storename
belongs_to :user
validates :user_id, :presence => true
end
and
User
class User < ActiveRecord::Base
attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :userimage, :remove_userimage
has_secure_password
has_many :gears
has_many :comments, :dependent => :destroy
has_one :store, :dependent => :destroy
before_save :create_remember_token
require 'carrierwave/orm/activerecord'
mount_uploader :userimage, UserpicUploader
accepts_nested_attributes_for :store
...
end
When someone creates a new user account I need to automatically create a new store for that user I was thinking within the user form. So how can I create a new store object that's linked to the new user being created?
Here is my code from the User Controller for CreateAction
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
redirect_to #user, :flash => {:success => "Welcome to Equiptme"}
else
render 'new'
#title = "Sign up"
end
end
View
<div class="signup_container">
<div class="signup_container_interior">
<%= provide(:title, 'Sign up') %>
<%= form_for(#user) do |f| %>
<% if #user.errors.any? %>
<div>
<div>
The form contains <%= pluralize(#user.errors.count, "error") %>.
</div>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li>* <%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :first_name %> <%= f.text_field :first_name, class: 'register_text_area' %>
</div>
</div>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :last_name %> <%= f.text_field :last_name, class: 'register_text_area' %>
</div>
</div>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :email %> <%= f.text_field :email, class: 'register_text_area' %>
</div>
</div>
<!--************STORE FIELDS ************** -->
<!--************STORE FIELDS END ************** -->
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :password %> <%= f.password_field :password, class: 'register_text_area' %>
</div>
</div>
<div class="register_field">
<div class="register_nonerror_container">
<%= f.label :password_confirmation %> <%= f.password_field :password_confirmation, class: 'register_text_area' %>
</div>
</div>
<div class="actions">
<%= f.submit "Create Account", class: 'register_button' %>
</div>
<% end %>
</div>
</div>
You can use the build_association method created along with the has_one relationship between users and stores:
def create
#user = User.new(params[:user])
#user.build_store
# etc
end
If you don't need the store until you've saved the user, you might also use create_association:
if #user.save
#user.create_store
# etc
end
You may want to take a look at this:
http://railscasts.com/episodes/196-nested-model-form-part-1

Resources