I have upgraded my app to rails 5.2 and inclined to use ActionText since old trix-editor/gem is no longer working.
Now new posts display their "descriptions" but how can I display my old posts' DESCRIPTIONS with the new installed ActionText?
post.rb has_rich_text :description
posts_controller.rb
...params.require(:post).permit(:description)
_form.html.erb
<%= f.rich_text_area :description %>
show.html.erb
<%= #post.description %>
Descriptions are only fetching from new records in ActionText but not displaying from existing "description" columns for old posts
I had a similar issue and I couldn't find a clean solution in the rails repo or anywhere. As a workaround, in your case, I would try:
show.html.erb: .
<%= #post.try(:description).body || #post[:description] %>
That wont solve the issue, but it would help you to populate old post values.
This answer worked for me. It also has the added bonus of cleaning up your database of the tables used for the normal (non-rich) text content.
"Assuming there's a 'content' in your model and that's what you want to migrate, first, add to your model: "
has_rich_text :content
"then create a migration"
rails g migration MigratePostContentToActionText
class MigratePostContentToActionText < ActiveRecord::Migration[6.0]
include ActionView::Helpers::TextHelper
def change
rename_column :posts, :content, :content_old
Post.all.each do |post|
post.update_attribute(:content, simple_format(post.content_old))
end
remove_column :posts, :content_old
end
end
You can find the original solution I used here
https://github.com/rails/rails/issues/35002#issuecomment-562311492
Related
I am using a blog engine in my Rails project called Lines, and blog posts are contained in a table called LinesArticle.
I want to add a custom attribute to hide certain posts behind a paywall, so I ran the following migration and raked it successfully:
class AddPaywallToLinesArticles < ActiveRecord::Migration
def change
add_column :lines_articles, :paywall, :string
end
end
Each blog post added to this table is posted through a form in the UI contained in my views/Lines/articles folder. I added a new text_field (where the user would write yes or no, I know I could do this through a Boolean but wanted to use a string just to test it).
<div class="input-field checkbox">
<%= f.label :paywall %><br>
<%= f.text_area :paywall%>
The form now loads and shows a text_area; however, that text is not saved when I submit the form. Example output if I check the last record in the table:
<LinesArticle id: 5, title: "Test 2 with False", teaser: nil, insider: nil, paywall: nil>
So the paywall column is not updating with the string I am typing in. I don't think it's an issue with the form -- I am wondering if the real issue is that I need to set some sort of permits: -- this blog engine does not have a Controller associated with it though.
Any ideas?
Your problem is most likely due to a missing strong parameter in your controller:
def create
...
#lineArticle = LinesArticle.create(line_article_params)
...
end
private
def line_article_params
params.require(:line_article).permit(:title, :teaser, :insider, :paywall)
end
I am working on status feature for my rails app. I have everything set up and it works perfectly fine. For the interface, I am using the best_in_place gem to allow users to edit in place for the status. The code is given below.
<% if #scoreboard.status.content.present? %>
<div id="statuscontent">
<%= render 'statusedit' %>
</div>
<% else %>
<%= render 'statusupdate' %>
<% end %>
The statusedit partial contains the best_in_place code and the statusupdate partial contains the normal form for creating the status. Codes for both partials are given below.
statusedit
<%= best_in_place [#scoreboard, #status], :content, place_holder: "Enter a status", as: "textarea" %>
<%= link_to "delete", [#scoreboard, #status], method: :delete, data: {confirm: "Are you sure"} %>
statusupdate
<%= form_for [#scoreboard, #status] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.text_area :content, class: "form-control", id:"status" %>
<%= f.submit "Post", class: "btn btn-primary", id: "status-button" %>
<% end %>
The above code is working perfectly fine, however, I am struggling to set up the interface I want. The problem is that best_in_place editing only works if the status has been created before. Therefore, I have to create the status using the form and then I can use in place editing. However, I want the interface such that users can use in place editing without the need of physically creating a status first. Is there a way to create a default status for every user? Or a before_update function that maybe creates a status before the user tries to update.
I tried using Ajax for creating status to achieve the interface but it didn't work as intended. Also, I feel there must be a simpler solution to this problem. I tried setting :default => "please upload status" in the database but that doesn't actually create a default record. It acts like a placeholder but you still have to click post for the record to be created. Is there a way to somehow automatically create a default status for each user or set a value in the database. I have read a few stack-overflow posts on this but nothing really points to the right direction. There must be a simpler way of doing this in rails. Any documentation or suggestions would be a great help. As always, any help is always greatly appreciated!! Thanks
I have added the relevant migration and model files.
status model
class Status < ActiveRecord::Base
belongs_to :scoreboard
end
scoreboard model
class Scoreboard < ActiveRecord::Base
has_one :status
end
Status migration file
class CreateStatuses < ActiveRecord::Migration
def change
create_table :statuses do |t|
t.text :content
t.references :scoreboard, index: true
t.timestamps null: false
end
add_foreign_key :statuses, :scoreboards
end
end
Answer for your questions.
Is there a way to create a default status for every user ?
Yes
You could create a default record in database after change_column.
def up
change_column :users, :admin, :boolean, default: false # I'm assuming you are saving default as false in users table but you could change accordingly all thing.
end
before_update function that maybe creates a status before the user tries to update.
instead of before_update one could use after_save callback.
As mentioned in official Document
after_save runs both on create and update, but always after the more
specific callbacks after_create and after_update, no matter the order
in which the macro calls were executed.
And lastly
There must be a simpler way of doing this in rails
Use ActiveRecord Migrations.
Apologies if this answer is not specific; you wrote a lot.
You're best setting a default value for an attribute at the database level.
Yes, you can use the before_create callback:
#app/models/scoreboard.rb
class Scoreboard < ActiveRecord::Base
before_create :set_default_status
private
def set_default_status
self[:status] = "default"
end
end
The problem with this is that it adds application-level logic which can be handled by the db:
$ rails g migration CreateStatusDefault
# db/migrate/create_status_default________.rb
class CreateStatusDefault < ActiveRecord::Migration
def change
change_column :scoreboards, :status, default: "Default"
end
end
$ rake db:migrate
Creating a default value in the db basically means that unless you send a value from your model at create / update, you're going to get the default.
The beauty of setting it in the DB is that your Rails app has absolutely zero work to do for it, making it much more efficient.
--
I subsequently found that your status "object" is actually a model in itself, which is probably where your issues are coming from.
If that is the case, you'll need to build the associative object before you create your main/parent one:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :statuses
before_create -> (model) { model.statuses.build }
end
We use this to build a profile for each User who signs up to our applications; it creates a "blank" associative record for your parent model.
This is something which would give you a "blank" status object, but as you've not posted your code, I really don't know.
A good tip with SO is code > text.
If in doubt, post code.
Is there a way to create a default status for every user?
Yep you can write it yourself. Something like this ...
User < ActiveRecord::Base
has_many :statuses
after_create :create_first_status
def create_first_status
self.statuses.create some_status_attribute: "some value"
end
end
I have a Rails project and I use the scaffold to generate my models and CRUD. Now I'm updating some models because I needed more columns or associations.
But I notices that all the columns I've added later than the scaffold are never updated from my form. I added the field manually in the form but nothing is written in the database.
In my case, I have three entities:
Document and People which both belongs to User.
When I generated the scaffold for People, I didn't have the association to User at first, and I added it with the following migration script:
class AddUserRefToPeople < ActiveRecord::Migration
def change
add_reference :people, :user, index: true, foreign_key: true
end
end
And to be able to update through my form, I added the same thing I had in my Document's form which is working very well:
<div class="field form-group">
<%= f.label :user, class: '...' %>
<div class="col-sm-10">
<%= f.select :user_id, options_for_select(User.all.map{|s| [s.firstname, s.id]}), class: '...' %>
</div>
</div>
It seems that the binding between the form and the model doesn't exist for this field (only for People entity because it works for Document).
And I have the same problem on Document on another column. The only pattern I found is the fact that I added those columns after doing the scaffold generation.
Do I miss something ? Do I need to do my update differently ? What is the best practice for adding new columns ?
Let me know if you need more information.
Seeing as the documentation for this gem is absolutely useless for beginners like myself (they the docs it doesn't say which code needs to go in which file), I figured I might get some better help here for my Rails 4 app instead of the official docs.
I'm not sure if acts-as-taggable-on is the best solution for my problem, but here's what I'm trying to do: I'm creating a business directory that works with tags instead of categories so that a bar/lounge can belong to both a bar, and a lounge. Perhaps someone knows a better solution instead of using acts-as-taggable-on?
There are no errors when I try to create or view the tags, but the problem is that the tags arent' being saved. When I try to view the business which has tags, it shows up empty. Same thing when I try to edit it.
This is what my model looks like:
class Business < ActiveRecord::Base
validates :name, uniqueness: true
acts_as_taggable
acts_as_taggable_on :tag_list
end
The form:
<%= form_for(#business) do |f| %>
...
<div class="field">
<%= f.label :tag_list, "Tags (seperated by commas)" %><br>
<%= f.text_field :tag_list %>
</div>
...
<% end %>
The view:
<p>
<strong>Tags:</strong>
<%= #business.tag_list %>
</p>
Anyone know what is preventing the tags from being viewed/saved?
Perhaps there's better documentation out there that someone could provide.
update: I'm also using Active_Admin, which seems to be causing some problem according to Matt Boldt. After following his tutorial my problem remains unsolved.
possible it is an array issue? not sure. what version of acts_as_taggable are you using?
try adding to your strong params to ask for an array.
def business_params
params.require(:business).permit(:xxx, :xxx, :tag_list => [])
end
I had the same problem and changing :tag_list => [] with :tag_list fixed it
I guess it depends by the type of input you use in your form, in my case was a text input
def business_params
params.require(:business).permit(:xxx, :xxx, :tag_list)
end
I was having the same problem and checked Terminal to see where the error had occurred, I got this
Unpermitted parameters: tag_list
I had forgotten to add :tag_list to the strong params accepted attributes in the controller for the model I was using tags with. Try that!
I'm pretty new to rails, and brand new to using the paper_trail gem.
I would like to show a list of each change made to the location or tag number of my assets model. I have installed paper_trail and it seems to be working correctly. In my view I have this:
<% #asset.versions.order('created_at DESC').each do |version| %>
On <%= version.created_at %> <%= version.whodunnit %> updated this asset.<br>
<ul>
<li>Asset relocated from "<%= version.last.locaton %>" to "<%= version.location %> "</li>
<li>User changed from "<%= version.last.tag_number %>" to "<%= version.tag_number %> "</li>
</ul>
<% end %>
This gives me the correct information for when the change was made and who made it, but I cannot figure out to display the lines that say (for instance): Asset relocated from "223" to "258 or Tag Number changed from "1173" to "1175".
Ideally I would only show information for things that have changed. So if the location changed but the tag number did not, I would show only the location line.
I don't really even know where to start. Any help would be appreciated. Thanks!
From The PaperTrail Documentation:
PaperTrail has an optional table column that can be used when creating versions called object_changes. This will store ONLY the changes made between versions. Which will allow you to just display the changes between each version. It works like this.
>> widget = Widget.create :name => 'Bob'
>> widget.versions.last.changeset # {'name' => [nil, 'Bob']}
>> widget.update_attributes :name => 'Robert'
>> widget.versions.last.changeset # {'name' => ['Bob', 'Robert']}
>> widget.destroy
>> widget.versions.last.changeset # {}
If you recently added paper_trail to your model then you can run a migration to add this column. This will track future changes.
class AddObjectChangesColumnToVersions < ActiveRecord::Migration
def self.up
add_column :versions, :object_changes, :text
end
def self.down
remove_column :versions, :object_changes
end
end
I recently had a need to get the changes, however, we have years of version data for 20+ models and adding that migration would only help in the future and not give me all of the data changes in the past.
I wound up creating a patch for PaperTrail that added methods like diff_previous, diff_next, diff_live which would give me the difference between versions. It was based off the idea of this patch of paper_trail(https://github.com/jeremyw/paper_trail/blob/master/lib/paper_trail/has_paper_trail.rb#L151-L156) but I implemented it quite differently. If you want more details I will see if I can open source that patch.