I have a website, where you can register for some events I called talks. After the registration the "guest" gets a confirmation email with a generated unsubscribe link.
The link opens a form with all the events listed that the guest registered for.
Now to unsubscribe from an event the guest has to uncheck the checkbox of the event. But I want it inverted so that they have to check the event to unsubscribe from it.
The models
class Guest < ApplicationRecord
has_and_belongs_to_may :talks
end
class Talk < ApplicationRecord
has_and_belongs_to_may :guests
end
The unsubscribe form
<%= form_for #guest do |f| %>
<% f.collection_check_boxes :talk_ids, #guest.talks, :id, :name do |b| %>
<%= b.check_box %>
<%= b.object.name %>
<% end %>
<input type="submit" value="Unsubscribe">
<% end %>
The update function after submitting
def update_talks
#guest = Guest.find(params[:id])
if #guest.update(guest_params)
redirect_to root_url
else
flash[:notice] = "Failed"
end
end
I couldn't find a solution so I hope you guys can tell me how to invert the checkbox?
Been a while, but I just ran into a similar issue where in some cases it is better for the interface to understand if the checked checkbox sets the boolean in the database to false.
This is the Rails 7 check_box method form_helper.rb:
def check_box(object_name, method, options = {}, checked_value = "1", unchecked_value = "0")
Tags::CheckBox.new(object_name, method, self, checked_value, unchecked_value, options).render
end
So you only need to change the checked_value to 0, the unchecked_value to 1 and toggle the checked option. In my case (imagine "method" is the boolean in the database:
= f.check_box :method, { checked: !f.object.method? }, '0', '1'
I'm a very beginner in Rails, but maybe it'll be better if the checkboxes come already checked
Related
In my rails app, I wish for the users to be able to upload multiple files at once.
I am using the carrierwave gem
gem 'carrierwave', github: 'carrierwaveuploader/carrierwave'
On the master branch which supposedly supports the multiple: true
found out in my internet searching desperation about the necessary addition of optional: true in my model for my attachment.
I'm using mysql so I can't use an array type in my database, but I've set up a has_many, belongs_to relationship between Request and Request_Attachment in my database.
my form:
<%= f.fields_for :request_attachments do |ra| %>
<div class="row" id="uploader">
<div class="col-xs-12">
<label class="btn btn-info"> Upload Files
<%= ra.file_field :file, multiple: true, name: "request_attachments[file][]", :style => "display: none" %>
</label>
</div>
</div>
<% end %>
my controller
#request = Request.new(request_params)
if #request.save
if params[:request][:request_attachments]
params[:request][:request_attachments]['file'].each do |f|
#request_attachment = #request.request_attachments.create!(:file => f)
end
end
flash[:success] = "Your request was submitted successfully, check your email for a confirmation message."
redirect_to action: 'index', status: 303
else
render :new
end
def request_params
params.require(:request).permit(:jobtitle, :requester, :status, request_attachments_attributes: [:id, :request_id, :file])
end
my models:
Request:
class Request < ApplicationRecord
has_many :request_attachments
accepts_nested_attributes_for :request_attachments
end
Request_Attachments:
class RequestAttachment < ApplicationRecord
mount_uploader :file, FileUploader
belongs_to :request, optional: true
end
I have tried variations of the form, like taking out the name portion.
When I remove the multiple: true portion, it will work perfectly, but it does not work with the multiple option.
I'm not quite sure where the issue may be, so any help would be great.
What is happening now is that the request gets saved, but
Only 1 request_attachment is created, and
The filename of the request_attachment is nil
Okay, I think I figured it out.
I made a couple changes, which threw an error, and I looked closely at the Parameter Hash, and I noticed essentially it looked like this:
{"utf8"=>"✓",
"request"=>
{"jobtitle"=>"Testing, again and again, and again",
"request_attachments_attributes"=>
{"0"=>
{"file"=>
[#<ActionDispatch::Http::UploadedFile:0x007fee9df806b8
#content_type="image/gif",
#headers="Content-Disposition: form-data; name=\"blah\"; filename=\"logo1.gif\"\r\nContent-Type: image/gif\r\n",
#original_filename="logo1.gif",
#tempfile=blah,
#<ActionDispatch::Http::UploadedFile:0x007fee9df80690
#content_type="image\gif",
#headers=
"Content-Disposition: form-data; name=\"blah\"; filename=\"Blah.gif\"\r\nContent-Type: image/gif\r\n",
#original_filename="Blah.gif",
#tempfile=blahblah]}}
I noticed the "0"=> and thought "wait.... what is that doing there?....
So I removed the name section in my form, and changed my controller to look like this:
if #request.save
params[:request][:request_attachments_attributes]["0"]['file'].each do |f|
#request_attachment = #request.request_attachments.create!(:file => f)
end
And that seemed to have worked.
I have been working on PHP. Presently trying to learn Ruby on Rails. I am learning Rails online, for now I am badly stuck on Sign-up or can say a form submission page. Sorry if it's too silly.
Error is:
undefined method new for nil:NilClass
Here is the code:
users_controller.rb
class UsersController < ApplicationController
def new
#user= User.new
end
def create
#user.new(params[:user])
if #user.save
flash[:notice]= "you signed up successfully"
flash[:color]= "valid"
else
flash[:notice]= "failed"
flash[:color]="invalid"
end
render "new"
end
end
new.html.erb
<% page_title="Signup" %>
<div class="Sign_Form">
<h1>Sign up</h1>
<%= form_for(:user, :url => {:controller => 'users', :action => 'create'}) do |f| %>
<p> Username:</br> <%= f.text_field :username%> </p>
<p> Email:</br> <%= f.text_field :email%> </p>
<p> Password:</br> <%= f.password_field :password%></p>
<p> Password Confirmation:</br> <%= f.password_field :password_confirmation%> </p>
<%= f.submit :Signup %>
<% end %>
<% if #user.errors.any? %>
<ul class="Signup_Errors">
<% for message_error in #user.errors.full_messages %>
<li>* <%= message_error %></li>
<% end %>
</ul>
<% end %>
</div>
user.rb
class User < ActiveRecord::Base
attr_accessor :password
EMAIL_REGEX = /^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i
validates :username, :presence => true, :uniqueness => true, :length => { :in => 3..20 }
validates :email, :presence => true, :uniqueness => true #:format => EMAIL_REGEX
validates :password, `enter code here`:presence =>true #:confirmation => true #password_confirmation attr
validates_length_of :password, :in => 6..20, :on => :create
end
In your users_controller > create, you put capital letter on User param.
For your case, it should be all lower case params[:user].
Side note, it actually depends on your attribute name you set on the form in the first place.
Edit:
In addition of that you should put #user = User.new(params[:user])
First thing you should create new object of User class
Second pass correct params key
change first line in create method to
#user = User.new(params[:user])
So the changed code will look like this:
class UsersController < ApplicationController
def new
#user= User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice]= "you signed up successfully"
flash[:color]= "valid"
else
flash[:notice]= "failed"
flash[:color]="invalid"
end
render "new"
end
end
change #user.new(params[:user]) to #user = User.new(params[:user]) I creates #user but it is not saved to database yet. On the line below #user.save that is when it gets saved. And remove render new because it will render the template with out setting the variables that the template needs. instead use redirect_to :new that will send the user to new and also set the variables needed
I guess you need to allow the params of User model in the User controller so as to avoid the forbidden error message as mentioned here. Please note that this is Rails feature as mentioned
Rails has several security features that help you write secure applications, and you're running into one of them now. This one is called strong parameters, which requires us to tell Rails exactly which parameters are allowed into our controller actions.
Thanks
I want to use a button inside HTML using information from the HTML itself.
More in detail:
There is a html.erb file. In there lay 2 <input type="hidden" name="Name" value='Tom'> and a Button.
Within the html.erb file i could get the value by typing params['Name']. But here comes my Problem. I have no idea how to write a button, so that it will only save #user when i click it. Therefore the method of the button should be something like:
#user.name = params["Name"]
#user.age = params["Age"]
#user.save
For me it looks like the simplest if i had this method(of the button) within the html, where #user, the name and the age are stored. But i'm a new to ruby, so what do i know.
In your controller where you have access to the params['Name'] and params['Age'] to save or update an existing one:
#user.name = params["Name"]
#user.age = params["Age"]
#user.save
A more Rails-y way, however is to use form_for to create a form for an object:
# show.html.erb (or whatever controller action the view is for)
<% form_for #user do |f| %>
<%= f.text_field :name %>
<%= f.text_field :age %>
<%= button_to "Save User" %>
<% end %>
# user_controller.rb
# If creating:
#user = User.new(params[:user])
# or for updating: (no need for save)
# #user.update_attributes(params[:user])
#user.save
Since the :age and :name will be passed in the :user hash looking like this:
user: {
name: "John",
age: 18
}
which can be passed to User.new or #user.update_attributes and it will set #user.name and #user.age from the hash.
I suggest browsing the saving data in the controller section of the Rails guides
I'm working on a form that should allow users to update a session variable called session[:city] that tracks their location. The variable doesn't need to be saved in the database cause it's kind of a throwaway; it only needs to exist while the user is on the site.
session[:city] is used in several places throughout the site, so I've placed the following method in the Application Controller:
class ApplicationController < ActionController::Base
before_filter :set_city
def set_city
unless session[:city].present?
session[:city] = request.location.city
end
if params[:city].present?
session[:city] = params[:city]
end
end
end
That part works correctly, and I'm able to call the variable throughout the site.
The issue I'm having is in updating the variable by a form. The only action I need it to do is update the variable, but it's not responding. I know I'm missing something here, but after trying a bunch of things I'm a bit stumped. This is my basic form currently:
<%= form_tag do %>
<%= text_field_tag :city, params[:city] %>
<%= submit_tag %>
<% end %>
Edited to working code
This will not work in production like environment where you have multiple worker process to serve the requests(unicorn or passenger). Each process will have its own memory. If the value is changed during a request processed by one worker process, other processes will not have the updated value.
You should be using session to store this information.
You can try something like this:-
<%= form_tag do %>
<%= text_field_tag :person, :city, :name => "city" %>
<%= submit_tag %>
<% end %>
class ApplicationController < ActionController::Base
before_filter :set_city
def set_city
unless session[:city].present?
session[:city] = params[:city] || request.location.city
end
end
end
The conditions needed to be split into 2 statements: an unless to set the session[:city] and an if to check if any params were being passed.
class ApplicationController < ActionController::Base
before_filter :set_city
def set_city
unless session[:city].present?
session[:city] = request.location.city
end
if params[:city].present?
session[:city] = params[:city]
end
end
end
And the working form:
<%= form_tag root_path do %>
<%= text_field_tag :city, params[:city], :placeholder => "#{session[:city]}: Change City" %>
<% end %>
I've been staring at this for a while and Google hasn't helped much so I'm turning to you guys for help. This should be a pretty simple fix.
The goal of the code is to take an email address from a sign up field and place it in the database.
I think most of what I need is there but I'm getting this error:
undefined method model_name for NilClass:Class
My home.html.erb file contains the following:
<%= form_for(#signup) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit "Enter" %>
</div>
<% end %>
The model contains this:
class Signup < ActiveRecord::Base
attr_accessible :email
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates(:email, :presence => true,
:length => {:maxiumum => 40},
:format => {:with => email_regex})
end
The controller contains:
class SignupController < ApplicationController
def show
end
def new
#signup = Signup.new
end
def create
#signup = Signup.new(params[:id])
if #signup.save
else
render 'new'
end
end
end
The problem is most likely because of an instance variable that you're using in your form_for not being set to an ActiveRecord object. It appears that you are setting it correctly in your "new" action, but it's not clear that you're rendering the correct template since you mention the form being in "home.html.erb"?
Either way, ensure that whatever you're using in the form_for is set to a valid ActiveRecord object and your problem may be solved.
In addition, you may want to change your create action to use all the params from the form:
#signup = Signup.new(params[:signup])
Add this to the home action in the pages controller:
#signup = Signup.new
The reason for the error is that you are using #signup in your form, but you didn't define it in your show controller action.