having issues converting slim to erb - ruby-on-rails

I have this slim syntax:
= form_for(#influencer.relationships.build(followed_id: #influencer.id)) do |f|
div = f.hidden_field :followed_id
= f.submit "Follow", class: "btn btn-large btn-primary"
This is the erb i came up but it doesn't work.
<%= form_for(#influencer.relationships.build(followed_id: #influencer.id)) do |f| %>
<% f.hidden_field :followed_id %>
<%= f.submit "Follow" %>
<% end %>

<%= form_for #influencer.relationships.build(followed_id: #influencer.id) do |f| %>
<%= f.hidden_field :followed_id %>
<%= f.submit "Follow" %>
<% end %>
Conversely, it's bad practice to build an object out of the controller scope. #influencer.relationships.build(followed_id: #influencer.id) should be done inside the controller:
#app/models/influencer.rb
class Influencer < ActiveRecord::Base
has_many :relationships, foreign_key: :follower_id
end
#app/controllers/relationships_controller.rb
class RelationshipsController < ApplicationController
def new
#influencer = Influencer.find params[:influencer_id]
#relationship = #influencer.relationships.build #-> "followed_id" SHOULD be a foreign key in the model. If you have it in the model, you won't need to explicitly define it
end
end
Thus, you'll get:
<%= button_to "Follow", #relationship %>

Related

unable to create or update a belongs_to record in Rails 4

I'm new to Rails and struggling to get my belongs_to association right. I have an app where a painting belongs to an artist and an artist can have_many paintings. I can create and edit my paintings, however I can not edit or create artists except through the console. Through much Googling I feel I have got myself turned around. Any help would be much appreciated!
Here's my routes.rb file:
MuseumApp::Application.routes.draw do
resources :paintings
resources :paintings do
resources :artists
resources :museums
end
root 'paintings#index'
end
Here's my paintings Controller
def show
#painting = Painting.find params[:id]
end
def new
#painting = Painting.new
##artist = Artist.new
end
def create
safe_painting_params = params.require(:painting).permit(:title, :image)
#painting = Painting.new safe_painting_params
if #painting.save
redirect_to #painting
else
render :new
end
end
def destroy
#painting = Painting.find(params[:id])
#painting.destroy
redirect_to action: :index
end
def edit
#painting = Painting.find(params[:id])
end
def update
#painting = Painting.find(params[:id])
if #painting.update_attributes(params[:painting].permit(:title, :image)) #safe_params
redirect_to #painting
else
render :edit
end
end
Here's the form in my paintings view:
<%= form_for(#painting) do |f| %>
<fieldset>
<legend>painting</legend>
<div>
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div>
<%= f.label :image %>
<%= f.text_field :image %>
</div>
<%= form_for([#painting,#painting.create_artist]) do |f| %>
<div>
<%= f.label :Artist %>
<%= f.text_field :name %>
</div>
</fieldset>
<%= f.submit %>
<% end %>
<% end %>
Artists Controller:
class ArtistsController < ApplicationController
def index
#artists = Artist.all
#artists = params[:q] ? Artist.search_for(params[:q]) : Artist.all
end
def show
#artist = Artist.find params[:id]
end
def new
#artist = Artist.new
end
def create
#painting = Painting.find(params[:painting_id])
#artist = #painting.create_artist(artist_params)
redirect_to painting_path(#painting)
end
def destroy
#artist = Artist.find(params[:id])
#Artist.destroy
redirect_to action: :index
end
def edit
#artist = Artist.find(params[:id])
end
def update
#painting = Painting.find(params[:painting_id])
#artist = #artist.update_attributes(artist_params)
redirect_to painting_path(#painting)
end
end
private
def artist_params
params.require(:artist).permit(:name)
end
Index view:
<h1> Hello and Welcome to Museum App</h1>
<h3><%= link_to "+ Add To Your Collection", new_painting_artist_path %></h3>
<%= form_tag '/', method: :get do %>
<%= search_field_tag :q, params[:q] %>
<%= submit_tag "Search" %>
<% end %>
<br>
<div id="paintings">
<ul>
<% #paintings.each do |painting| %>
<li><%= link_to painting.title, {action: :show, id:painting.id} %> by <%= painting.artist_name %></li>
<div id = "img">
<br><%= link_to (image_tag painting.image), painting.image %><br>
</div>
<%= link_to "Edit", edit_painting_path(id: painting.id) %>
||
<%= link_to 'Destroy', {action: :destroy, id: painting.id},method: :delete, data: {confirm: 'Are you sure?'} %>
<% end %>
</ul>
</div>
In your case you should use accepts_nested_attributes_for and fields_for to achieve this.
Artist
has_many :paintings, :dependent => :destroy
accepts_nested_attributes_for :paintings
Painting
belongs_to :artist
And also you should try creating artist with paintings like this
form_for(#artist) do |f| %>
<fieldset>
<legend>Artist</legend>
<%= f.label :Artist %>
<%= f.text_field :name %>
<%= fields_for :paintings, #artist.paintings do |artist_paintings| %>
<%= artist_paintings.label :title %>
<%= artist_paintings.text_field :title %>
<%= artist_paintings.label :image %>
<%= artsist_paintings.text_field :image %>
</fieldset>
<%= f.submit %>
<% end %>
Note:
You should be having your Artist Controller with at least new,create,edit and update methods defined in it to achieve this.
Edit
Try the reverse
Artist
has_many :paintings, :dependent => :destroy
Painting
belongs_to :artist
accepts_nested_attributes_for :paintings
form_for(#painting) do |f| %>
<fieldset>
<legend>Painting</legend>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :image %>
<%= f.text_field :image %>
<%= fields_for :artists, #painting.artists do |ff| %>
<%= ff.label :Artist %>
<%= ff.text_field :name %>
</fieldset>
<%= f.submit %>
<% end %>
Put this form in paintings views.

rails how to pass nested parameters

I have a strong parameter like this
params.require(:survey).permit( option_booleans_attributes: [:id, :survey_id, :topic, :answer])
if I use rails f.input I got parameter like
"option_booleans_attributes"=>{"0"=>{"answer"=>"true", "id"=>"5"}, "1"=>{"answer"=>"false", "id"=>"6"}, "2"=>{"answer"=>"true", "id"=>"7"}}}
but I need to show option_booleans topic and let user fill answer
<% #survey.option_booleans.each do |question| %>
<%= question.topic %><br>
<%= radio_button "option_booleans_attributes[]", "answer[#{question.id}]", "true" %>是
<%= radio_button "option_booleans_attributes[]", "answer[#{question.id}]", "false" %>否<br>
<% end %>
But I don't know how to generate the 0 1 2 in the parameter..
about my survey.rb
class Survey < ActiveRecord::Base
has_many :option_booleans
accepts_nested_attributes_for :option_booleans
belongs_to :member
end
class OptionBoolean < ActiveRecord::Base
belongs_to :survey03
and OptionBoolean have topic:string and answer:boolean
I want to let user see the topic and update the answer
It seems you're missing several parts of your form:
#app/controllers/surveys_controller.rb
def new
#survey = Survey.new
#survey.option_booleans.build #-> creates ActiveRecord Object for your form
end
#app/views/surveys/new.html.erb
<%= form_for #survey do |f| %>
<%= f.fields_for :option_booleans do |option| %>
<% #survey.question_booleans.each do |question| %>
<%= question.topic %>
<%= f.radio_button "answer[#{question.id}]", "true" %>
<%= f.radio_button "answer[#{question.id}]", "false" %>
<% end %>
<% end %>
<% end %>
Although I don't quite understand how your system works
You have a survey with many options, but you're passing new attributes to create new options each time. Surely you'd have option_booleans as a join model, with options as an independent model, and:
#app/models/survery.rb
Class Survey < ActiveRecord::Base
has_many :option_booleans
has_many :options, through: :option_booleans
end
What I use now
<li><% #survey03.option_booleans.each do |question| %>
<%= question.topic %><br>
<%= radio_button "option_booleans_attributes[#{question.id}]", "answer", "true", :required => true %>
<%= radio_button "option_booleans_attributes[#{question.id}]", "answer", "false", :required => true %>
<% end %></li>
and in controller
params[:option_booleans_attributes].each do |option_id, attributes|
if option = OptionBoolean.find_by_id(option_id)
option.update_attributes(attributes)
end
end
and I know if I want to generate index just use
<% #survey.option_booleans.each_with_index do |question, index| %>
<%= question.topic %><br>
<%= radio_button "option_booleans_attributes[#{index}]", "answer[#{question.id}]", "true" %>
<%= radio_button "option_booleans_attributes[#{index}]", "answer[#{question.id}]", "false" %>
<% end %>
try select options like this:
#variable_with_booleans = [true, false]
<%= f.select :param, #variable_with_booleans %>
answer to your latest comment:
I don't sure, but try to edit your form
<%= form_for #question do |f| %>
<%= f.label :topic %>
<% #variable_with_booleans = [true, false] %>
<%= f.select :answer, #variable_with_booleans %>
<%= f.submit %>
<% end %>
and edit your strong params in controller,which contains this action

Acessing and add records from other controller

I have a model
class Rcomment < ActiveRecord::Base
attr_accessible :comment, :rating
belongs_to :recipe
belongs_to :user
end
I'm trying to add comment via the show view of recipe. I populated rcomment table with dummy data and it's showing fine via:
#recipe = Recipe.find(params[:id])
#comments = #recipe.rcomments
So I tried
#newcomments = #recipe.rcomments.build(params[:recipe])
But it doesn't work at all with an error:
undefined method `rcomments_path' for #<#:0x25ccd10>
How do I get it to display a usable form_for?
%= form_for(#newcomments) do |f| %>
<%= f.label :Comments %>
<%= f.text_field :comment%>
<%= f.label :ratings %>
<%= f.text_field :rating %>
<%= f.submit "Submit Comment", class: "btn btn-large btn-primary" %>
<% end %>
You've created a form for Rcomment creation, but you don't have an rcomments entry in your routes.rb. However, I think what best fits your problem is creating rcomments through a recipe. You can do this with accepts_nested_attributes_for and fields_for.
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
So, something like this--
In your Recipe model, add:
attr_accessible :rcomments_attributes
accepts_nested_attributes_for :rcomments
And in your recipes#show view:
<%= form_for(#recipe) do |f| %>
<% f.fields_for :rcomments do |cf| %>
<%= cf.label "Comments" %>
<%= cf.text_field :comment%>
<%= cf.label "Ratings" %>
<%= cf.text_field :rating %>
<% end %>
<%= f.submit "Submit Comment", class: "btn btn-large btn-primary" %>
<% end %>

Nested model/form doesn't create an entry

While delving into ruby's nested models I encountered an issue.
Consider the following scenario,
I have the following models:
Author
Book
With the following specifications:
Author:
class Author < ActiveRecord::Base
attr_accessible :name
has_many :books, dependent: :destroy
accepts_nested_attributes_for :books #I read this is necessary here: http://stackoverflow.com/questions/12300619/models-and-nested-forms
# and some validations...
end
Book:
class Book < ActiveRecord::Base
attr_accessible :author_id, :name, :year
belongs_to :author
#and some more validations...
end
I would like to add a book to an author. Here is my authors_controller:
def new_book
#author = Author.find(params[:id])
end
def create_book
#author = Author.find(params[:id])
if #author.books.create(params[:book]).save
redirect_to action: :show
else
render :new_book
end
end
And this is the form with which I try doing it:
<h1>Add new book to <%= #author.name %>'s collection</h1>
<%= form_for #author, html: { class: "well" } do |f| %>
<%= fields_for :books do |b| %>
<%= b.label :name %>
<%= b.text_field :name %>
<br/>
<%= b.label :year %>
<%= b.number_field :year %>
<% end %>
<br/>
<%= f.submit "Submit", class: "btn btn-primary" %>
<%= f.button "Reset", type: :reset, class: "btn btn-danger" %>
<% end %>
Problem:
When I type in the data and click "submit" it even redirects me to the correct author, but it doesn't save a new record for that author.
After a lot of research I can't seem to find what I am doing wrong here.
Change authors_controller to:
def new_book
#author = Author.find(params[:id])
#book = Book.new
end
Your form to:
<h1>Add new book to <%= #author.name %>'s collection</h1>
<%= form_for ([#author, #book]), html: { class: "well" } do |f| %>
And, routes.rb
resources :authors do
resources :books
end
You're missing a couple of things.
Controller:
...
def new_book
#author = Author.find(params[:id])
#author.books.build
end
...
View, it is f.fields_for and not just fields_for:
<%= f.fields_for :books do |b| %>
<%= b.label :name %>
<%= b.text_field :name %>
<br/>
<%= b.label :year %>
<%= b.number_field :year %>
<% end %>
You also need to add :nested_attributes_for_books on your Author model accessible methods. The create method on you Author controller doesn't need any code additions to get going.
Note: You set the Books controller to render 'books#show' on success. If the app is redirecting you to the author that means the Author controller is handling the creation of the book, unless you set it to redirect to author and not the book.

undefined method `my_teas_path' for #<#<Class:0xa8930c8>:0xa578cf8>

My current goal in my first rails project is to have a button that will create a #my_tea using the attributes of a #tea (show page). This is the error I am getting:
'undefined method `my_teas_path' for #<#:0xa578cf8>
I have tried having the form in a _new partial inside my_teas/ and inside teas/_add_tea both have given me the same error. Anyway here is my code as it stands.
View:
<%= form_for([#user, #my_tea]) do |f| %>
<%= f.hidden_field :name, :value => #tea.name %>
<%= f.hidden_field :tea_type, :value => #tea.tea_type %>
<%= f.hidden_field :store, :value => #tea.store %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= fields_for [#user, #tea_relationship] do |r| %>
<%= r.hidden_field :tea_id, :value => #tea.id %>
<% end %>
<%= f.submit "Add Tea", class: "btn btn-large btn-primary" %>
<% end %>
my_tea controller
def new
#my_tea = MyTea.new
end
def show
#my_tea = MyTea.find(params[:id])
end
def create
#my_tea = MyTea.new(params[:my_tea])
if #my_tea.save
flash[:success] = "Tea added to your teas!"
else
redirect_to user_path
end
end
Teas controller:
def show
#tea = Tea.find(params[:id])
#my_tea = MyTea.new
#tea_relationship = TeaRelationship.new
end
Routes
resources :users do
resources :my_teas
end
resources :teas
Models:
class User < ActiveRecord::Base
has_many :my_teas, :dependent => :destroy
has_many :tea_relationships, :dependent => :destroy
class MyTea < ActiveRecord::Base
belongs_to :user
class TeaRelationship < ActiveRecord::Base
belongs_to :user, class_name: "User"
end
Tea model doesn't belong to anything.
Please help rails community your my only hope :p
Update
changing my form to this
<%= form_for([#user, #my_tea]) do |f| %>
<%= f.hidden_field :name, :value => #tea.name %>
<%= f.hidden_field :tea_type, :value => #tea.tea_type %>
<%= f.hidden_field :store, :value => #tea.store %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= fields_for #tea_relationship do |r| %>
<%= r.hidden_field :tea_id, :value => #tea.id %>
<% end %>
<%= f.submit "Add Tea", class: "btn btn-large btn-primary" %>
<% end %>
it works and the #my_tea submits but the #tea_relationship doesn't.
So by the look of things and glimpsing through, it seems like you are trying to do some nested forms. It also appears like you have a many-to-many relationship( tea.rb <=> tea_relationship.rb <=> my_tea.rb) Make sure your Models are set up correctly.
Many to Many
I am not sure why you are trying to do [#user, #my_tea]
Nested Forms
Should be more in the lines of
<%= form_for #my_tea, :url => posting_path do |f| %>
<%= f.simple_fields_for :teas, #my_tea.teas.build do |x| %>
...
<%end%>
...
<%end%>
hope that helps!

Resources