I'm very new to ruby on rails. Thanks for your patience in advance.
<div class="field">
<%= #pin.image_url if #pin.image? %>
<%= f.file_field :image %>
<%= f.hidden_field :image_cache %>
</div>
What does #pin.image? do?
There is not image? method in my controller. I'm guessing it's one of the helper functions provided by rails for every controller? Is that right?
What is f ?
here is my model for pin
class Pin < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
belongs_to :board
end
and its schema
class CreatePins < ActiveRecord::Migration
def change
create_table :pins do |t|
t.string :name
t.string :image
t.integer :board_id
t.timestamps null: false
end
end
end
class AddImageToPins < ActiveRecord::Migration
def change
add_column :pins, :image, :string
end
end
There is not image? method in my controller.
You don't call this method on your controller, but on your object assigned to #pin variable, which is probably your Pin model. And your model does have image? method.
What is f ?
It's the form builder object, passed into form_for block.
Related
I am new to Rails and working on a blog project.
I have articles and categories. Each article can have multiple categories and each category can belong to multiple articles.
I also have a join table articles_categories
My migrations:
class CreateArticles < ActiveRecord::Migration[5.2]
def change
create_table :articles do |t|
t.string :title
t.text :body
t.timestamps
end
end
end
class CreateCategories < ActiveRecord::Migration[5.2]
def change
create_table :categories do |t|
t.string :name
t.timestamps
end
end
end
class CreateArticlesCategoriesJoinTable < ActiveRecord::Migration[5.2]
def change
create_join_table :articles, :categories do |t|
t.index :article_id
t.index :category_id
end
end
end
My model associations:
class Article < ApplicationRecord
has_and_belongs_to_many :categories
end
class Category < ApplicationRecord
has_and_belongs_to_many :articles
end
This all makes sense so far.
What I am struggling with now, is how do I add categories when creating a new Article? I want to be able to select pre-defined categories from a list (stored in Category table) through a form.
What model and/or URL (if any) do I use in the form_with helper?
Is the following anywhere close?
<% form_with model: ???, url: ??? do |f| %>
<%= f.collection_select :category_id, Category.order(:name), :id, :name %>
<% end %>
I'm trying to accept decimals in my form:
<%= f.label :price %><br />
<%= f.number_field :price, :step => 0.01 %>
But anytime I type in a number like 13.75 in the form from the client side, it'll round the number down to just $13.00. This is the code to display the price:
<%= number_to_currency(#product.price) %>
I don't think the number_to_currency method has anything to do with it but I guess it's worth noting.
Any assistance will be greatly appreciated, thanks!
In your schema.rb file you should have
t.float "price"
instead of
t.integer "price"
or
t.string "price"
To do this, run rails g migration change_data_type_for_fieldname
Now a new migration file should appear in db/migrate:
class ChangeDataTypeForFieldName < ActiveRecord::Migration
def up
end
def down
end
end
Fill it with proper names:
class ChangeDataTypeForFieldName < ActiveRecord::Migration
def self.up
change_table :table_name do |t|
t.change :field , :new_datatype
end
end
def self.down
change_table :table_name do |t|
t.change :field, :old_data_type
end
end
end
Run rake db:migrate
I have successfully implemented the dynamic select menus for city and area models in my app.
now I have the following models:
class Pet < ActiveRecord::Base
belongs_to :pet_type
belongs_to :pet_category
belongs_to :pet_breed
end
class PetType < ActiveRecord::Base
has_many :pet_categories, through: :pet_type_categories
has_many :pet_type_categories
end
class PetCategory < ActiveRecord::Base
has_many :pet_types, through: :pet_type_categories
has_one :pet_type_category
end
class PetTypeCategory < ActiveRecord::Base
belongs_to :pet_type
belongs_to :pet_category
has_many :pet_breeds
end
class PetBreed < ActiveRecord::Base
belongs_to :pet_type_category
belongs_to :pet_Type
belongs_to :pet_category
end
migrations:
class CreatePetTypes < ActiveRecord::Migration
def change
create_table :pet_types do |t|
t.string :name
t.timestamps
end
end
end
class CreatePetCategories < ActiveRecord::Migration
def change
create_table :pet_categories do |t|
t.string :name
t.timestamps
end
end
end
class CreatePetTypeCategories < ActiveRecord::Migration
def change
create_table :pet_type_categories do |t|
t.references :pet_type, index: true
t.references :pet_category, index: true
t.timestamps
end
end
end
class CreatePetBreeds < ActiveRecord::Migration
def change
create_table :pet_breeds do |t|
t.string :name
t.references :pet_type_category, index: true
t.timestamps
end
end
end
The pet_type_category table is a join table for pet_types that share the same pet_categories.
So my question is how do I create 3 dynamic select menus of pet_type, pet_category and pet_breed in the create form?
Thanks
Edit: I managed to get the pet type collection_select and pet category grouped_collection_select done once I updated the relationships, now the 3rd one (pet breed) is what I'm stuck at..
I understand now after a bit of a research that it is not possible to have nested groups though surely It should be possible using some kind of helper, however for a lack of a better solution, I added to the PetTypeCategory model:
def pet_type_category_names
"#{self.pet_type.name} #{self.pet_category.name}"
end
and in my view now I have:
<div class="field">
<%= f.collection_select :pet_type_id, PetType.all, :id, :name, {prompt: "Choose your pet's type"} %>
</div>
<div class="field">
<%= f.grouped_collection_select :pet_category_id, PetType.all, :pet_categories, :name, :id, :name, {prompt: "Choose your pet's category"} %>
</div>
<div class="field">
<%= f.grouped_collection_select :pet_breed_id, PetTypeCategory.all, :pet_breeds, :pet_type_category_names, :id, :name, {prompt: "Choose your pet's breed"} %>
</div>
so for the 3rd select instead of having:
Dog
Small
Breed
I have:
Dog Small
Breed
I need (or I think) implement polymorphic association in my model but I have something wrong. Let see my situation, it's a simple question/answers system, and the logic is the following:
- a question can be ansewered by N answers.
- An answer can be only a "text" XOR (one or other, not both) a "picture".
Migrations:
class CreateAnswers < ActiveRecord::Migration
def change
create_table :answers do |t|
t.integer :question_id
t.references :answerable, :polymorphic => true
t.timestamps
end
end
end
class CreateAnswerTexts < ActiveRecord::Migration
def change
create_table :answer_texts do |t|
t.text :content
t.timestamps
end
end
end
class CreateAnswerPictures < ActiveRecord::Migration
def change
create_table :answer_pictures do |t|
t.string :content
t.timestamps
end
end
end
Models
*answer.rb*
class Answer < ActiveRecord::Base
belongs_to :user_id
belongs_to :question_id
belongs_to :answerable, :polymorphic => true
attr_accessible :answerable_type
end
answer_text.rb
class AnswerText < ActiveRecord::Base
TYPE = "text"
has_one :answer, :as => :answerable
attr_accessible :content
end
answer_picture.rb
class AnswerPicture < ActiveRecord::Base
TYPE = "picture"
has_one :answer, :as => :answerable
attr_accessible :content
end
Controller
answers_controller.rb:
...
def create
post = params[:answer]
create_answerable(post[:answerable_type], post[:answerable])
#answer = #answerable.answer.new()
end
private
def create_answerable(type, content)
#answerable = ('Answer' + type.capitalize).classify.constantize.new(:content => content)
#answerable.save
end
...
And view form (Only have these fields):
...
<div class="field">
<%= f.label :answerable_type %><br />
<%= select("answer", "answerable_type", Answer::Types, {:include_blank => true}) %>
</div>
<div class="field">
<%= f.label :answerable %><br />
<%= f.text_field :answerable %>
</div>
...
So, the problem is when I submit form I get this error:
undefined method new' for nil:NilClass
app/controllers/answers_controller.rb:52:increate'
Answers? :)
on a has_one relationship, you have to use :
#answerable.build_answer
or
#answerable.create_answer
instead of
#answerable.answer.new
see the reference for more info.
This question already has an answer here:
Can not call my associate table in my view
(1 answer)
Closed 8 years ago.
Can any kind person look at this and see what is wrong with the code. I really must not withdraw my fields in the associative table! what is my problem?
view:
<% #playersname.each do |p|%>
<ul>
<li><%= p.name %></li>
<li><%= p.result.inspect %></li>
</ul>
controller:
class ResultsController < ApplicationController
def index
#playersname = Player.all
end
end
model:
class Player < ActiveRecord::Base
attr_accessible :name
belongs_to :result
end
class Result < ActiveRecord::Base
# attr_accessible :title, :body
has_many :player
end
migrations:
class CreatePlayers < ActiveRecord::Migration
def change
create_table :players do |t|
t.string "name"
t.references :results
t.timestamps
end
end
end
class CreateResults < ActiveRecord::Migration
def change
create_table :results do |t|
t.string "result", :limit => 40
t.string "cal", :limit => 40
t.string "sum",:limit => 300
t.timestamps
end
end
end
You will need to pluralize player, here in your code:
has_many :player
should be
has_many :players
Also, in your view you should change:
<li><%= p.result.inspect %></li>
to something else. It won't work because a) there is no "result" method for p there is only a results method for it. And when you call .inspect on results you will get something you probably don't want to send to the browser.
Once you get the association figured out, you probably want something like the following in your view:
<h1>Results</h1>
<%= render :partial => "result", :collection => #results %>
and then you will create a partial in your views folder named _result.rb and containing code like this
<h3>Result: <%= result.title %></h3>
<p><%= result.body %></p>