I currently have a basic controller and model that creates a Subscriber with the normal attributes(name, email, phone, etc...), but I also have a visit attribute on the Subscriber. So I have a form that's rendered with the "new" action and save the input with the create action. << VERY BASIC >> The new feature I want to implement is create a new form that takes in only a phone_number and when the number is entered it update the visit attribute on the subscriber that that corresponds with that number. right now I'm struggling trying to figure this out with just one controller. I'll show my current controller and hopefully that will help for clarity.
CONTROLLER
class SubscribersController < ApplicationController
def index
#subscriber = Subscriber.all
end
def new
#subscriber = Subscriber.new
end
def create
#subscriber = Subscriber.create(subscriber_params)
if #subscriber.save
flash[:success] = "Subscriber Has Been successfully Created"
redirect_to new_subscriber_path(:subscriber)
else
render "new"
end
end
def visit
#subscriber = Subscriber.find_by_phone_number(params[:phone_number])
if #subscriber
#subscriber.visit += 1
#subscriber.save
redirect_to subscribers_visits_new_path(:subscriber)
else
render "new"
end
end
end
As you can see in the visit action I'm trying to implement this feature but I'm not sure where to go from here?
I suppose your search page has a form where you type the number you want to search for. And the request comes to visit action, where you'll increment the +1 to the visit count and then show the details of the number(subscriber).
def visit
#Comes request from search action
#subscriber = Subscriber.find_by_phone_number(params[:phone_number])
if #subscriber
#subscriber.visit += 1
#subscriber.save
redirect_to subscriber_path(#subscriber)
#It will show the details
else
flash[:alert] = "Didn't find with that number. Search again."
render :action => :search
end
end
Update:
Search logic
def search
#will render search.html.erb by convention
end
Inside search.html.erb
<%= form_tag({controller: "subscribers", action: "visit"}, method: "get") do %>
<%= text_field_tag :phone_number %>
<%= submit_tag "Submit" %>
<% end %>
So this will send params to visit action, and after incrementing it will render show method. Hope this helps. Let me know if there is anything.
Related
The error: undefined method `model_name' for nil:NilClass (NoMethodError)
I'm receiving this error when trying to render the haml below:
%section#banner
.row
.medium-12.columns
%h2 Add Testimonial
= simple_form_for(#testimonial) do |f|
.row
.large-6.columns
= f.input :text, as: :text,
placeholder: 'Use this space to write a testimonial about the event(s) you participated.'
.row
.large-6.columns
%p.description
= sanitize('Any testimonial along with your name and profile picture might be used for the promotion of codebar (website, prospectus, etc).')
.row
.large-12.columns.text-right
= f.submit 'Submit testimonial', class: 'button'
The controller is the following:
class TestimonialsController < ApplicationController
before_action :authenticate_member!
def get_testimonial
testimonial = Testimonial.where(member_id: testimonial_member_id)
invitations = current_user.workshop_invitations.accepted_or_attended
if invitations.any? and testimonial.blank?
render 'new'
else
render 'show'
end
end
def show
#testimonial = Testimonial.find(testimonial_member_id)
end
def new
#testimonial = Testimonial.new
end
def create
#testimonial = Testimonial.new(testimonial_params)
#testimonial.member_id = current_user
#testimonial.public = false
if #testimonial.save
redirect_to #testimonial
else
render 'new'
end
end
private
def testimonial_params
params.require(:testimonial).permit(:text)
end
def testimonial_member_id
params[current_user]
end
end
May someone help me see why is returning nil? If the variable is the same I'm passing on the new function?
AFAIK simple_form_for(#testimonial) will try to call #testimonial.model_name so that's where the problem most likely originates.
If you go through the get_testimonial controller, you can end up at:
render 'new'
and that will render the HAML in question. But, notice that nothing in get_testimonial initializes #testimonial so get_testimonial will end up trying to simple_form_for(nil).
Changing the bottom of get_testimonial to something more like this:
if invitations.any? && testimonial.blank?
#testimonial = Testimonial.new
render 'new'
else
render 'show'
end
Your show template presumably needs a #testimonial as well so you might want to say #testimonial = testimonial.first before render 'show' too.
Also, I've changed your and operator to && since you're generally better off pretending that and doesn't exist. The low precedence of and and or cause a lot of problems so you're better off sticking to && and ||.
I'm not sure of the logic for testimonials so you might be able to go with something more like:
def get_testimonial
#testimonial = Testimonial.find_by(member_id: testimonial_member_id)
invitations = current_user.workshop_invitations.accepted_or_attended
if invitations.any? && !#testimonial
#testimonial = Testimonial.new
render 'new'
else
render 'show'
end
end
You might want to revisit your testimonial_member_id method as well, this:
def testimonial_member_id
params[current_user]
end
looks odd, maybe it should be params[:id] instead.
Hey all so in my code I am just redirecting back to the index of all the topics and theoretically I would like to redirect back to the page.
this is my controller for this page, right now I am just using topics_path as a stand in.
class LikesController < ApplicationController
def index
end
def create
#bookmark = Bookmark.find(params[:bookmark_id])
like = current_user.likes.build(bookmark: #bookmark)
if like.save
flash[:notice] = "Successfully liked bookmark."
else
flash.now[:alert] = 'Error in liking bookmark. Please try again.'
end
redirect_to topics_path
end
def destroy
#bookmark = Bookmark.find(params[:bookmark_id])
like = current_user.likes.find(params[:id])
# Get the bookmark from the params
# Find the current user's like with the ID in the params
if like.destroy
flash[:notice] = "Successfully unliked bookmark."
else
flash.now[:alert] = 'Error in unliking bookmark. Please try again.'
end
redirect_to topics_path
end
end
this is the line from rake routes that I was to redirect_to
bookmarks_show GET /bookmarks/show(.:format) bookmarks#show
If you wish to redirect back to a specific topic's page... then you'll need to pass the topic_id through as a param so you can use it in the redirection.
Add it into the form/link you're using eg:
(note: totally making this up, obviously your code will be different)
<% form_for #like do |f| %>
<%= f.hidden_field :topic_id, #topic.id %>
Then in your create action, you just redirect using that eg:
def create
#bookmark = Bookmark.find(params[:bookmark_id])
like = current_user.likes.build(bookmark: #bookmark)
if like.save
flash[:notice] = "Successfully liked bookmark."
else
flash.now[:alert] = 'Error in liking bookmark. Please try again.'
end
redirect_to topic_path(:id => params[:topic_id])
end
Note: if you want to use some other page (eg the bookmark page) then use that instead... this is a "general howto" not a "use this code exactly as you see it here" :)
Probably a very simple problem I'm overlooking. I'm building a feature similar to Facebook's "home" page for logged in users. A user can post topics in one form, and that form works perfectly.
There is a comment form under each posted topic. When a user enters a comment and clicks the submit button the comment is created, but it is not shown unless I manually refresh the page. I can't see what I'm doing wrong here.
_form.html.haml
= form_for [topic, Comment.new], remote: true do |f|
.form-group
= f.text_area :body, rows: 2, class: 'form-control', placeholder: "Make a comment"
= f.submit "Post", class: 'f-button primary f-fw-bold post-btn'
I have tried using #topic for this form as well but get the error: undefined method `comments_path'
comments_controller.rb
class CommentsController < ApplicationController
def create
puts "TOPICS PARAMS",params[:topic_id]
#topic = Topic.find(params[:topic_id])
#comments = #topic.comments
#comment = current_user.comments.build( comment_params )
#comment.topic = #topic
#new_comment = Comment.new
if #comment.save
flash[:notice] = "Comment was created."
redirect_to topics_path
else
flash[:error] = "There was an error saving the comment. Please try again."
redirect_to topics_path
end
end
private
def comment_params
params.require(:comment).permit(:body, :topic_id)
end
end
All of this is rendered in the topics#index path, so here is the topics controller as well.
topics_controller.rb
class TopicsController < ApplicationController
def index
#topics = Topic.order(created_at: :desc)
#comments = Comment.all
#limited_partners = LimitedPartner.all
#users = User.all
#comment = Comment.new
end
def show
#topic = Topic.find(params[:id])
end
def create
#topic = Topic.new(topic_params)
#topic.user_id = current_user.id if current_user
#topic.limited_partner_id = current_user.limited_partner_id if current_user
if #topic.save
flash[:notice] = "Topic was saved successfully."
redirect_to topics_path
else
flash[:error] = "Error creating topic. Please try again."
render :new
end
end
def new
end
def edit
end
def update
end
private
def topic_params
params.require(:topic).permit(:body, :liked, :limited_partner_id, :user_id, :comment_id)
end
end
In the index.html.haml file I call the partial like this:
= render partial: 'comments/form', locals: { topic: topic, comment: #comment}
You are using remote: true for your form. So the submit will trigger an Ajax request. A javascript response will be returned, but no HTML will be updated by default.
You will need to sprinkle some javascript to update the HTML yourself: bind a callback to the ajax:success event, or use a js view (e.g. app/views/comments/create.js.erb).
Have also a look at Turbolinks 3 (still in development), which can reduce the amount of custom javascript required for partial page updates.
Your problem likely lies here ...
= form_for [topic, Comment.new], remote: true do |f|
Try this instead
= form_for #new_comment, url: {controller: 'comments', action: 'create'}, method: "post", remote: true do
and be sure your config/routes.rb looks something like this
get "/some-path", to: "comments#create"
post "/some-path", to: "comments#create"
I had to use javascript to get better control over the form and data. So I made a topic.coffee file with this:
$ ->
$('.new_comment').on 'submit', (event) =>
form = $(event.target).closest('form')
topicCommentsId = form.attr('action').replace(/\//g, '_').substring(1)
owningCommentsSection = $('#' + topicCommentsId)
formData = form.serialize()
$.post form.attr('action'), formData, (data) =>
extractedBody = $(data.substring(data.indexOf('<body')))
topicComments = extractedBody.find('#' + topicCommentsId)
owningCommentsSection.html(topicComments.html())
form.find('[name="comment[body]"]').val('')
location.reload();
return false
I removed the remote: true from my form as well and identify each topic in my index.html.haml with this:
.f-grid-row.topic_comments{id: "topics_#{topic.id}_comments"}
- topic.comments.each do |comment|
- if comment.topic_id == topic.id || comment.post_id == topic.id
...
I'm trying to put a new form that creates new "Addicts" in a modal in my home page.
It's a simple form with 2 inputs, that when clicking on New, a modal pops up with that form in my index page.
I can't get it to work because it keeps saying "Couldnt find Addict without an ID".
My Pages Controller
class PagesController < ApplicationController
def home
#addict = Addict.find(params[:id])
#lanzaderas = Lanzadera.all
render 'index'
end
end
My Addict Controller
class AddictsController < ApplicationController
def index
#posts = Addict.all
end
def show
#addict = Addict.find(params[:id])
end
def new
#addict = Addict.new(params[:addict])
end
def create
#addict = Addict.new(params[:addict])
if #addict.save
redirect_to posts_path, :notice => "Your Addict was saved"
else
render "new"
end
end
def edit
end
def update
end
def destroy
end
end
end
My form in my modal
<%= form_for #addict do |f| %>
<%= f.input :name %>
<%= f.input :surname %>
<%= f.input :postal %>
<%= f.submit %>
<% end %>
I know it has something to do with the variable / id not being passed correctly in my Controller, but it's an error I get lots of times and don't know why I happens.
Thanks!
In def home in your PagesController you have this code:
#addict = Addict.find(params[:id])
I suspect, that you don't have the id for 'addict' in your parameters, when you visit your home action.
Do you want to display one particular addict in your 'home' page? If not, you can remove this line.
Update:
Change this in your AddictsController:
def new
#addict = Addict.new
end
In the new action you only "prepare" a new addict object. Using the find method is not possible, since the record hasn't been created yet.
If you're using Rails 4 you also have to permit your parameters (for security reasons; more info here: Railsguides: Strong Parameters)
In your case you have to do 2 things:
First: add this at the bottom of your AddictsController:
private
def addict_params
params.require(:addict).permit(:name, :surname, :postal)
end
Second: use this method in your create action instead of params[:addict]:
def create
#addict = Addict.new(addict_params)
if #addict.save
redirect_to posts_path, :notice => "Your Addict was saved"
else
render "new"
end
end
I have a #miniatures model and a #lines model joined via a #minilines model.
In the #miniature show view I have this link
<%= link_to "Add to product line", new_miniline_path(:miniature_id => #miniature) %>
To a New #miniline form that takes the :miniature_id from a hidden field like so
<%= f.hidden_field :miniature_id, :value => #miniature.id %>
And then you select the desired #line from a dropdown.
This all works. What I can't get to work is for the controller to redirect a user back to the originating #miniature after the create action works.
This is what I have in my new and create actions in the controller
def new
#miniline = Miniline.new(#miniature)
#miniature = Miniature.find(params[:miniature_id])
#lines = Line.all
end
def create
#miniline = Miniline.new(miniline_params)
if #miniline.save
flash[:success] = "Miniature added to product line"
redirect_to miniature_path(#miniature)
else
flash[:success] = "Did not work!!!"
render 'new'
end
end
I've tried various alternatives to miniature_path(#miniature) like plain #miniature and miniature_path(:miniature_id) but to no avail. I suspect my problem is with the passing of the :miniature_id to the #minilines model. Any help very much appreciated as I've been banging my head for an hour or two.
redirect_to miniature_path(#miniline.miniature)
Assuming you have an association setup.
You haven't set #miniature in create which is that that doesn't work
You could also do
redirect_to #miniline.miniature