I can't call my new variable, why not? - javascript

I'm new in rails, so I do not master even the subtleties of this langage.
I meet an error which say undefined method 'prix' for Online::ActiveRecord_Associations when I try to call my variable "prix" and "portion" into the post index.
So I can I do that ?
My code :
Onlines controller :
class OnlinesController < ApplicationController
before_action :authenticate_user!
before_action :set_post
before_action :owned_online, only: [:new, :edit, :update]
before_action :set_online
def index
#post = Post.all.order('created_at DESC')
end
def new
#online = current_user.onlines.build
#online.post_id = #post.id
#online.user_id = current_user.id
end
def create
#online = #post.onlines.create(online_params)
#online.user_id = current_user.id
#online.post_id = #post.id
if #online.save(online_params)
#online.update(push: true)
#online.update(pushed_at: Time.zone.now)
flash[:success] = 'Votre post est en ligne !'
redirect_to post_path(#post)
else
render 'new'
end
end
def show
end
def update
if #onlines.update(online_params)
if #online.push == false
if #online.portion <= 1
#online.update(push: false)
flash[:success] = 'Veuillez indiquer le nombre de parts disponibles '
redirect_to root_path
else
#online.update(push: true)
flash[:success] = 'Votre post a bien été pushé !'
redirect_to root_path
end
end
else
#user.errors.full_messages
flash[:error] = #user.errors.full_messages
render :edit
end
end
private
def online_params
params.require(:online).permit(:user_id, :post_id, :prix, :portion, :push, :pushed_at)
end
def owned_online
#post = Post.find(params[:post_id])
unless current_user == #post.user
flash[:alert] = "That post doesn't belong to you!"
redirect_to :back
end
end
def set_post
#post = Post.find_by(params[:post_id])
end
def set_online
#post = Post.find(params[:post_id])
#online = Online.find_by(params[:id])
end
end
Onlines/Index view :
<div class="title text-center">
<h1>Alors ? On mange quoi ?</h1>
</div>
<br>
<%= render 'posts/post' %>
posts /post view :
<div class="row">
<%-#posts.each do |post|%>
<div class="post">
<div class="form-group text-center">
<h3> <%=post.title%></h3>
</div>
<p> Posted by : <%= link_to post.user.pseudo, profile_path(post.user.pseudo) %>, <%= time_ago_in_words(post.created_at) %> ago </p>
**<p><%= post.onlines.prix %></p>
<p><%= #online.portion %></p>**
<div class="image text-center">
<div class="image-border">
<%= link_to (image_tag post.image.url(:medium), class:'img-responsive'), post_path(post)%>
</div>
</div>
</div>
<% end %>
</div>
</div>
</div>
So, if you have any ideas, tell me please.

In your posts/post.html.erb
**<p><%= post.onlines.prix %></p>
You encountered the error undefined method 'prix' for Online::ActiveRecord_Associations because posts.onlines is a collection of one or more Online objects, and NOT a single Online record.
By this, I meant that the following values may differ (as an example):
post.onlines.first.prix
post.onlines.last.prix
If you want to select just the #online record for every specific post in your <%-#posts.each do |post|%>
loop, then you could just do the following
posts/post.html.erb
...
**<p><%= #online.prix %></p>
<p><%= #online.portion %></p>**
...
Or if you want to show all prix values for each Online record in post.onlines, then you could do the following
posts/post.html.erb
...
<% post.onlines.each do |online| %>
**<p><%= online.prix %></p>
<% end %>
<p><%= #online.portion %></p>
...

Related

AJAX button processes, doesn't change

I've found a lot of people with the same problem I have, but none of the solutions apply to my situation. I am following Michael Hartl's tutorial here. I have a follow system set up in accordance with chapter 14 (I'm using the latest edition of the book, as I am on Rails 5.1). The follow/unfollow button processes in the database, but I have to manually refresh the page to see the button and follow count change.
I get this in the browser console log:
POST 500 (Internal Server Error)
jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js:10255
send # jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js:10255
ajax # jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js:9739
ajax # jquery_ujs.self-784a997f6726036b1993eb2217c9cb558e1cbb801c6da88105588c56f13b466a.js:94
handleRemote # jquery_ujs.self-784a997f6726036b1993eb2217c9cb558e1cbb801c6da88105588c56f13b466a.js:179
(anonymous) # jquery_ujs.self-784a997f6726036b1993eb2217c9cb558e1cbb801c6da88105588c56f13b466a.js:512
dispatch # jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js:5227
elemData.handle # jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js:4879
relationships_controller.rb:
class RelationshipsController < ApplicationController
before_action :authenticate_user!
def create
user = User.find(params[:followed_id])
current_user.follow(user)
respond_to do |format|
format.html { redirect_to(:back) }
format.js
end
end
def destroy
user = Relationship.find(params[:id]).followed
current_user.unfollow(user)
respond_to do |format|
format.html { redirect_to(:back) }
format.js
end
end
end
views/users/_follow.html.erb:
<%= form_for(current_user.active_relationships.build, remote: true) do |f| %>
<div><%= hidden_field_tag :followed_id, #user.id %></div>
<%= f.submit "Follow", class: "btn btn-primary" %>
<% end %>
views/users/_unfollow.html.erb
<%= form_for(current_user.active_relationships.find_by(followed_id: #user.id),
html: { method: :delete }, remote: true) do |f| %>
<%= f.submit "Unfollow", class: "btn" %>
<% end %>
views/users/_follow_form.html.erb
<% if current_user != #user %>
<div id="follow_form">
<% if current_user.following?(#user) %>
<%= render 'unfollow' %>
<% else %>
<%= render 'follow' %>
<% end %>
</div>
<% end %>
relationships/create.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/unfollow')) %>");
$("#followers").html('<%= #user.followers.count %>');
relationships/destroy.js.erb
$("#follow_form").html("<%= escape_javascript(render('users/follow')) %>");
$("#followers").html('<%= #user.followers.count %>');
users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!, only: [:index, :edit, :update, :destroy,
:following, :followers]
def index
#page_title = "Forge Users"
#users = User.all
end
def show
#user = User.find(params[:id])
#posts = Post.all
end
def following
#title = "Following"
#user = User.find(params[:id])
#users = #user.following
render 'show_follow'
end
def followers
#title = "Followers"
#user = User.find(params[:id])
#users = #user.followers
render 'show_follow'
end
end
What am I doing wrong?
You set local variable user
def create
user = User.find(params[:followed_id])
but reference class instance variable #user in your .js.erb template.
$("#followers").html('<%= #user.followers.count %>');
Instead, set #user = User.find(params[:followed_id]) so it is available to the views. Actually, I think you are trying to set #user = current_user. That might make more sense.
You need to rename your Javascript files to have .erb ending.
relationships/create.js.erb and relationships/destroy.js.erb. It's because you have Ruby in the file so it has to process the Ruby before it gets interpreted as Javascript and sent back.
http://guides.rubyonrails.org/working_with_javascript_in_rails.html#a-simple-example

rails 5 undefine template error

i am creating rails 5 and adding comment to a show action which is displayed in modal
in my show action for comment i have it like this
#selfie = Selfy.find(params[:id])
respond_to do |format|
format.js
end
with this i cant get the show through modal like this
<%= link_to fetch_selfy_path(selfie.id), class: "show_lightbox", data: { featherlight: "mylightbox" }, remote: true do %>
<img class="card-main-image" src="<%= selfie.photo.url if selfie.photo.url %>" alt="Image Alt text">
<% end %>
<div class="lightbox" id="lightbox">
<%=render partial: "selfies/show", locals: { selfie: selfie } %>
</div>
after clicking on the button we show action together with a comment
<% selfie.comments.each do |comment| %>
<%= render partial: "selfies/comments/comment", locals: { comment: comment } %>
<% end %>
where the partial looks like
<p> <b><%= comment.user.username %>: </b><%= comment.body %></p>
all this works fine until i try to inject the new commect through ajax
addCommentToSelfie("<%= j render "selfies/comments/comment", locals: { comment: #comment } %>");
this returns and error of
ActionView::Template::Error (undefined local variable or method `comment' for #<#<Class:0x007f207400c648>:0x00557937265830>):
1:
2: <p> <b><%= comment.user.username %>: </b><%= comment.body %></p>
app/views/selfies/comments/_comment.html.erb:2:in `_app_views_selfies_comments__comment_html_erb__4557429192479440105_46989553619000'
i tried different methond but still getting same error
You're mixing up different syntaxes with some mixing up of quotes too. If you use locals: ... you must also use partial:, or omit both in this case...
addCommentToSelfie("<%= j render 'selfies/comments/comment', comment: #comment %>");
based on the answers provide above, i was able to solve my issue
first i clean my creat.js.erb to
$("#comments").append("<%= j render partial: 'selfies/comments/comment', locals: { comment: #comment } %>");
secondy was getting error nil class because i wasnt using instant variable in my comments controller
from:
def create
comment = #selfie.comments.new(comment_params)
comment.user = current_user
comment.save
end
TO:
def create
#comment = #selfie.comments.new(comment_params)
#comment.user = current_user
#comment.save
respond_to do |format|
format.js
end
from there everything works smoothly
Could you show us the action create in the comment controller ? Usually, I do something like that.
def create
#comment = #selfie.comments.new(comment_params)
#comment.user = current_user
respond_to do |format|
if #comment.save
format.html { redirect_to #comment }
format.js
else
render :new
end
end
end
Then in your view, you should have the file comments/create.js.erb that contains your js :
addCommentToSelfie("<%= j render 'selfies/comments/comment', comment: #comment %>");
And now #comment should exist.

Photo preview is shown but photo is not saved in form: using Carrierwave and preview photo with JS

I'm trying to update a profile picture from a user through a (edit)-form. I want to show the user which photo it is trying to upload, so I've used JS to preview the selected photo. The problem is that the preview is showing, but the new photo isn't saved through the form.
Any ideas on what I might have missed?
edit.html.erb
<%= f.inputs do %>
<% if #user.photo? %>
<div id="photo_edit">
<img id="img_prev" class="profile_photo_edit" src="<%= current_user.photo %>">
<label id="photo-edit-button">
<input type='file' onchange="readURL(this);" />
<%= f.file_field :photo %>
<%= f.hidden_field :photo_cache %>
<span>Wijzig foto</span>
</label>
</div>
<% else %>
<div id="photo_edit">
<%= image_tag "PICA.jpg", :id => "img_prev", :class => "profile_photo_edit"%>
<label id="photo-edit-button">
<input type='file' onchange="readURL(this);" />
<%= f.file_field :photo %>
<%= f.hidden_field :photo_cache %>
<span>Wijzig foto</span>
</label>
</div>
<% end %>
photo-preview.js
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img_prev')
.attr('src', e.target.result)
.width(100)
.height(100);
};
reader.readAsDataURL(input.files[0]);
}
}
users_controller.rb
class Profile::UsersController < ApplicationController
skip_before_filter :verify_authenticity_token
before_action :correct_user, only: [:edit, :update]
def index
# pagination
#users = User.order(:name)
query = params[:search].presence || "*"
#results = User.search params[:search], page: params[:page], per_page: 9
# #results = User.search params[:search], where: {id: {not: current_user.id}}
end
def create
#user = User.new(user_params)
if #user.save
redirect_to :action => 'show'
else
render :action => 'edit'
end
end
def new
#user = current_user
end
def show
#user = User.find(params[:id])
map
#competences = #user.competences.all
end
def edit
#user = User.find(params[:id])
#profiles = Profile.all
#locations = Location.all
#positions = Position.all
#competences = Competence.all
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
print "--------"
#bla = []
#usercompetence = #user.competences
# Insert / add expertises
for competence in params[:expertises]
print competence
if competence.blank?
next
end
print "\n"
comp_object = nil
if Competence.exists?(id: competence)
comp_object = Competence.find(competence)
elsif Competence.exists?(name: competence, user_id: current_user.id)
comp_object = Competence.where(name: competence, user_id: current_user.id).first()
else
comp_object = Competence.new(name: competence, user_id: current_user.id, category: "expertise")
comp_object.save
end
print "adding..."
print comp_object[:name]
print comp_object[:category]
print "\n"
#bla << comp_object
unless #usercompetence.include?(comp_object)
#usercompetence << comp_object
end
end
# Insert / add expertises
for competence in params[:competenties]
print competence
if competence.blank?
next
end
print "\n"
comp_object = nil
if Competence.exists?(id: competence)
comp_object = Competence.find(competence)
elsif Competence.exists?(name: competence, user_id: current_user.id)
comp_object = Competence.where(name: competence, user_id: current_user.id).first()
else
comp_object = Competence.new(name: competence, user_id: current_user.id, category: "competence")
comp_object.save
end
print "adding..."
print comp_object[:name]
print comp_object[:category]
print "\n"
#bla << comp_object
unless #usercompetence.include?(comp_object)
#usercompetence << comp_object
end
end
# Delete competences from user
print "--------"
for competence in #usercompetence
print "Checking.."
print competence[:name]
unless #bla.include?(competence)
print "Delete..."
#usercompetence.delete(competence)
end
end
print "-------------"
#user.save
redirect_to :action => 'show'
end
end
def destroy
Profile.find(params[:id]).destroy
redirect_to :action => 'new'
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :current_position, :position_description, :email, :phonenumber, :linkedin, :skype, :location_id, :location_specs, :photo, :photo_cache)
end
def map
#user = User.find(params[:id])
if #user.location_id
#location = Location.find(#user.location_id)
end
#hash = Gmaps4rails.build_markers(#location) do |location, marker|
marker.lat location.latitude
marker.lng location.longitude
end
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless #user == current_user
end
end
user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
mount_uploader :photo, PhotoUploader
searchkick
paginates_per 6
before_save :generate_competence?
belongs_to :location
has_one :profile, dependent: :destroy
has_and_belongs_to_many :competences
def search_data
attributes.merge(
competence_name: competences.map(&:name),
location_name: location(&:name)
)
end
end

rails create pages by hash with nested resources

image
as image, i'd like to make page with nested resources.
my plan is
register user
create tour(request input informations by params)
if #tour.tour_days(params) value is over 1
create day pages as much as the number of user put into tour_day params
so i want to create page like(if 1user create first tour and put 3 into tour_day)
localhost:3000/tours/1/days/1
localhost:3000/tours/1/days/2
localhost:3000/tours/1/days/3
(if 1user create second tour and put 2 into tour_day)
localhost:3000/tours/2/days/1
localhost:3000/tours/2/days/2
i'd like to create these pages by automatically when user put number into tour_day and click submit button from tour_view
i've done create nested resources and throw data but i can't make clearly.. ;(
the reason i nest resources and create additional controller(day_controller) is afterwords i'd like to add recommendation function(recommendation for whom couldn't make schedule)...
actually i'd like to make page like airbnb(creating room process)
(Am i doing right process??)
tour_controller
class ToursController < ApplicationController
before_action :set_tour, only:[:show, :edit, :update]
before_action :authenticate_user!, except:[:show]
def index
#tours = current_user.tours
end
def show
end
def new
#tour = current_user.tours.build
end
def create
#tour = current_user.tours.build(tour_params)
i = 0
if #tour.save
redirect_to new_tour_day_path(#tour.id, #day), notice: "Saved Your Tour Courses"
else
render :new
end
end
def edit
end
def update
if #tour.update(tour_params)
redirect_to edit_tour_day_path(#tour.id, #day), notice: "Updated Your Tour Courses"
else
render :edit
end
end
private
def set_tour
#tour = Tour.find(params[:id])
end
def tour_params
params.require(:tour).permit(:tour_title, :tour_theme, :tour_summary, :tour_language, :tour_day, :tour_member, :tour_car, :tour_camera, :price)
end
end
day_controller
class DaysController < ApplicationController
before_action :set_tour
before_action :set_day, only: [:show, :edit, :update]
before_action :authenticate_user!, except:[:show]
def index
end
def show
end
def new
#tour = current_user.tours.find(params[:tour_id])
#day = #tour.days.build
end
def create
#tour = current_user.tours.find(params[:tour_id])
#day = #tour.days.build(day_params)
if #day.save
redirect_to edit_tour_day_path(#tour.id, #day), notice: "Saved Your Tour Courses"
else
render :new, notice: "Errors"
end
end
def edit
end
def update
if #day.update(day_params)
redirect_to edit_tour_day_path(#day), notice: "Updated Your Tour Courses"
else
redner :edit
end
end
private
def set_tour
#tour = Tour.find(params[:tour_id])
end
def set_day
#day = Day.find(params[:id])
end
def day_params
params.require(:day).permit(:day_number)
end
end
tour_view(test page)
<div class="container">
<%= form_for #tour, :html => { multipart: true } do |f| %>
<div class="col-md-3 select">
<div class="form-group">
<label>Maximum Tour Day</label>
<%= f.select :tour_day, [["1",1], ["2",2], ["3",3], ["4",4]], prompt: "Select...", class: "form-control" %>
</div>
</div>
<div class="actions">
<%= f.submit "save", class: "btn btn-primary" %>
</div>
<% end %>
</div>
day_view(test page)
<div class="container">
<%= form_for [:tour, #day] do |f| %>
<label>day_number</label>
<%= f.text_field :schedule_, class: "form-control" %>
<div class="actions">
<%= f.submit "Save", class: "btn btn-primary"%>
</div>
<% end %>
</div>
** additionally
Inside of Day view
i'd like to create schedule like
image
when i click an icon, the form appear and make detail tour schedule with ajax.
how can i approach to create this function??
----
this is my first project of web programming, im so confusing
plz... give me some(lots of) help...
----
im using rails 5.0.0.1 and rails 2.3.1

How to update two _form from one submit?

How can the current_user update his email, if he chooses, without having to have a separate submit button?
current code
<%= form_for(#challenge) do |challenge| %>
<%= challenge.action %>
<%= challenge.send_email %>
<% end %>
<%= form_for(current_user) do |user| %>
<%= user.email %>
<%= user.submit %>
<% end %>
<%= form_for(#challenge) do |challenge| %>
<%= challenge.submit %>
<% end %>
overall idea
<%= form_for(#challenge) do |challenge| %>
<%= challenge.action %>
<%= challenge.send_email %>
<%= form_for(current_user) do |user| %> # Or somehow remove form_for(current_user) altogether while still being able to update current_user.email within the form_for(#challenge)
<%= user.email %>
<% end %>
<%= challenge.submit %>
<% end %>
image of _form
Offering controllers code to see if we can make this work via fields_for
challenges_controller
class ChallengesController < ApplicationController
before_action :set_challenge, only: [:show, :edit, :update, :destroy, :challenging, :mark_accomplished, :mark_completed, :create_freebie, :like]
respond_to :html, :json
def show
#challenge_to_deadline = current_user.challenges.group_by {|i| i.deadline} if current_user
#notable = #challenge
#notes = #notable.notes
#note = Note.new
#commentable = #challenge
#comments = #commentable.comments
#comment = Comment.new
#correct_user = current_user.challenges.find_by(id: params[:id])
end
def new
#challenge = Challenge.new
respond_modal_with #challenge, location: root_path
end
def edit
end
def create
#challenge = Challenge.new(challenge_params)
if params[:step] == '2'
if current_user == nil
# If there is no user, store the lifetime values to the session.
session[:challenge_action] = challenge_params[:action]
session[:challenge_committed] = challenge_params[:committed]
session[:challenge_deadline] = [params["challenge"]["deadline(3i)"], params["challenge"]["deadline(2i)"], params["challenge"]["deadline(1i)"]].join('/')
session[:challenge_date_started] = [params["challenge"]["date_started(3i)"], params["challenge"]["date_started(2i)"], params["challenge"]["date_started(1i)"]].join('/')
session[:challenge_order] = challenge_params[:order]
session[:challenge_days_challenged] = challenge_params[:days_challenged]
session[:challenge_why] = challenge_params[:why]
session[:challenge_conceal] = challenge_params[:conceal]
redirect_to signup_path
else
#challenge = current_user.challenges.build(challenge_params)
if #challenge.conceal == true
#challenge.save
redirect_to root_path
if #challenge.date_started.present?
flash[:info] = 'habit Challenge secretly saved! Click "Strike 1" upon incompleting a day.'
else
flash[:info] = 'goal Challenge secretly saved! Click checkmark upon completing it.'
end
elsif
#challenge.save
track_activity #challenge
redirect_to root_path
if #challenge.date_started.present?
flash[:info] = 'habit Challenge saved! Click "Strike 1" upon incompleting a day.'
else
flash[:info] = 'goal Challenge saved! Click checkmark upon completing it.'
end
else
respond_modal_with #challenge
end
end
end
end
def update
#challenge.update(challenge_params)
flash[:info] = 'Challenge updated'
respond_modal_with #challenge, location: root_path
end
private
def set_challenge
#challenge = Challenge.find(params[:id])
end
def challenge_params
params.require(:challenge).permit(
:action,
:why,
:like,
:deadline,
:accomplished,
:tag_list,
:conceal,
:archive,
:trigger,
:missed_days,
:target,
:reward,
:order,
:date_started,
:date_ended,
:days_challenged,
:completed_at,
:freebie,
:freebie_date,
:send_email => [],
:committed => [])
end
end
users_controller
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
before_action :correct_user, only: [:edit, :update]
def show
#user = User.find(params[:id])
#past_challenges = #user.challenges.publish.order("deadline ASC").select{ |challenge| challenge.deadline < Date.current if challenge.deadline.present? }
#past_challenges_by_years = #past_challenges.group_by { |t| t.deadline.beginning_of_year }
#present_oneshot_challenges = #user.challenges.unaccomplished.publish.order("deadline ASC").select{ |challenge| challenge.deadline == Date.current if challenge.deadline.present? }
#present_habit_challenges = #user.challenges.unaccomplished.publish.order("date_started DESC").select{ |challenge| challenge.date_started <= Date.tomorrow if challenge.date_started.present? }
#future_challenges = #user.challenges.unaccomplished.publish.order("deadline ASC").select{ |challenge| challenge.deadline > Date.current if challenge.deadline.present? }
#future_challenges_by_years = #future_challenges.group_by { |t| t.deadline.beginning_of_year }
#inspirations = #user.inspirations.publish
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
action = session.delete(:challenge_action)
deadline = session.delete(:challenge_deadline)
committed = session.delete(:challenge_committed)
date_started = session.delete(:challenge_date_started)
order = session.delete(:challenge_order)
days_challenged = session.delete(:challenge_days_challenged)
why = session.delete(:challenge_why)
conceal = session.delete(:challenge_conceal)
# Create
if deadline.present?
#user.challenges.create(action: action, deadline: deadline, why: why, conceal: conceal, date_started: date_started, committed: committed, days_challenged: days_challenged)
end
#user.send_welcome_email
log_in #user
redirect_to tutorial_url
flash[:info] = 'Let the games begin! Add another challenge with + Challenge'
else
render 'new'
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
redirect_to root_url
flash[:success] = "Settings updated"
else
render 'edit'
end
end
private
def user_params
if params[:conceal] = true
params.require(:user).permit(:time_zone, :name, :email, :tag_list, :password, :conceal, inspirations_attributes: [:name, :tag_list, :conceal], activities_attributes: [:conceal, :action, :trackable_id, :trackable_type])
else
params[:user][:conceal] = false
params.require(:user).permit(:time_zone, :name, :image, :tag_list, :email, :password, inspirations_attributes: [:name, :tag_list], activities_attributes: [:action, :trackable_id, :trackable_type])
end
end
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please sign in first"
redirect_to root_url
end
end
# Confirms the correct user.
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
end
Embedding form within another form is not valid html. There can be multiple forms with in a page, but they cannot be embedded within each other.
If you want to have fields for different models with in the same form, depending upon the association between those models, you could make use of fields_for within the form_for to render the form fields from those models. And then when the form is submitted, again depending upon the associations between the models, you could persist the data.
You could also make use of javascript and submit/update parts of the form. For example: when the contents of the text_field have changed, you could trigger an AJAX request and persist the data.
Refer to FormHelper#fields_for for more info.
Update:
Based on your response in the comments, as you have the following models:
class User < ActiveRecord::Base
has_many :challenges
end
class Challenge < ActiveRecord::Base
belongs_to :user
end
You have two approaches.
Approach 1: Through controller action filters. Intercept the user's email from the params in the controller and update it. Something like:
class ChallengesController < ApplicationController
before_action :update_user_email, if: proc {|c| c.current_user.present? && c.params[:email].present? }
private
def update_user_email
email = params[:email]
current_user.update_attribute(:email, email)
end
end
And update your form code as follows:
<%= form_for(#challenge) do |challenge| %>
# include fields for challenge
<%= text_field_tag :email, current_user.email %>
<%= challenge.submit %>
<% end %>
Approach 2: Through model callbacks. Using a combination of attr_accessor and the callbacks in the model.
class Challenge < ActiveRecord::Base
belongs_to :user
attr_accessor :user_email
before_save :update_user_email, if: :user_email_present?
protected
def user_email
self.user.email if self.user.present?
end
def user_email_present?
self.user_email.present?
end
def update_user_email
# based on your logic in controller, looks like the
# `current_user` and the `user` of the `challenge`
# are one and the same. So you could directly update
# `email` on the `user` object.
self.user.update_attribute(:email, self.user_email)
end
end
And update your form code as follows:
<%= form_for(#challenge) do |challenge| %>
# include fields for challenge
<%= challenge.text_field :user_email, current_user.email %>
<%= challenge.submit %>
<% end %>

Categories

Resources