Problem ze związkami

Witam mam modele Article, Photo oraz User związane następującymi relacjami:

Article
belongs_to :user
has_many :photos
User
has_many :articles
has_many :photos
Photo
belongs_to :article
belongs_to :user

w tabeli Article mam jeden klucz głowny: user_id po to by mieć informację o użytkowniku który dodał artykul
w tabeli Photo mam dwa klucze główne: user_id oraz article_id by mieć inforację o uzytkowniku który dodal zdjęcia oraz do jakiego artykulu zostały one dodane

Aby zapisać user_id w tabeli articles w kontrolerze mam @article.user_id = current_user.id if current_user i to działa
W tabeli photos article_id zapisuje się natomiast user_id jest NULL, nawet gdy w kontrolerze photos w metodzie create zrobiłem podobnie jak w kontrolerze Article czyli;
@photo.user_id = current_user.id if current_user niestety user_id w tej tabeli jest null

show me the code!

Z tego co piszesz powinno być wszystko ok, więc zamiast opisywać kod po prostu go pokaż :wink:

pamiętaj też o methodach:

logger.info @string Rails.logger.info @string (rails 3) raise @string puts @string =debug @object
w metodach, które przyjmują stringa jako parametr możesz robić np. coś takiego:

puts @object.inspect
raise @object.inspect

Bez całego kodu kontrolera (metod create) to trudno tutaj wyrokować, gdzie jest błąd. Ale zasadnicze pytanie - potrzebne Ci jest user_id w Photo? Przecież Photo należy do artykułu, który należy do użytkownika. Nie jest tak, że zawsze takie foto będzie należało do właściciela artykułu?

W zasadzie user_id będzie mi potrzebne w tablicy photos gdyż naprzykład User może dodawać obiekty photo do galerii nie tworząc przy tym artykułu, i tak samo w tabeli
articles user_id będzie mi potrzebny gdyż artykuł może być stworzony bez zdjęć.

Poniżej kod:
photos_controller:

def create @photo = Photo.new(params[:photo]) @photo.user_id = current_user.id if current_user respond_to do |format| if @photo.save flash[:notice] = 'Photo was successfully created.' format.html { redirect_to(@photo) } format.xml { render :xml => @photo, :status => :created, :location => @photo } else format.html { render :action => "new" } format.xml { render :xml => @photo.errors, :status => :unprocessable_entity } end end end
articles_controller

def create @article = Article.new(params[:article]) @article.user_id = current_user.id if current_user respond_to do |format| if @article.save flash[:notice] = 'Artykuł został poprawnie dodany do bazy danych.' format.html { redirect_to(@article) } format.xml { render :xml => @article, :status => :created, :location => @article } else format.html { render :action => "new" } format.xml { render :xml => @article.errors, :status => :unprocessable_entity } end end end

To musisz skorzystać z metod o których Ci napisałem wcześniej.
np. gdzieś z widoku daj sobie:

<%= debug current_user %>

i zobacz co Ci wypluje.

Z tego co piszesz wygląda na to, że po prostu nie ma current_user’a

Kurcze własnie że current_user jest w chwili tworzenia nowego artykułu:

[code]— !ruby/object:User
attributes:
name: “”
salt: ***
created_at: 2010-08-26 13:04:22
activated_at: 2010-08-26 13:04:32
crypted_password: ***
remember_token_expires_at:
updated_at: 2010-08-26 13:04:32
deleted_at:
activation_code:
id: “1”
remember_token:
login: ***
email: ***
state: active
attributes_cache: {}

roles:

  • !ruby/object:Role
    attributes:
    name: Administrator
    created_at:
    authorizable_type:
    updated_at:
    role_id: “1”
    id: “1”
    authorizable_id:
    user_id: “1”
    attributes_cache: {}

    readonly: true[/code]

Teraz podam inny kod może to pomoże:
Widok metody new dla articlews_controller:

[code]<%= debug current_user %>

  <% semantic_form_for(@article, :html => {:multipart => true}) do |f| %>

    <% f.inputs :name => "Treść i kategoria artykułu" do %>
      <%= f.input :title, :label => "Tytuł" %>
      <%= f.label(:wstęp_do_artykułu, :synopsis, :required => true) %>
      <%= f.tinymce_managed :synopsis, :width => '600px', :height => '200px' %>
      <%= f.label(:treść_artykułu, :body, :required => true) %>
      <%= f.tinymce_managed :body, :width => '600px', :height => '400px' %>
      <%= f.input :published, :label => "Publikować?", :as => :radio %>
      <%= f.input :categories, :label => "Kategoria", :as => :check_boxes, :collection => nested_set_options(Category, @category) {|i| "#{'-' * i.level} #{i.name}" }, :for => :categories %>
    <% end %>
    
    <% f.inputs :name => "Autorzy i Fotografowie Artykułów" do %>
      <%= f.input :authors, :label => "Autorzy", :as => :check_boxes, :collection => Author.find(:all) %>
      <%= f.input :photographers, :label => "Fotografowie", :as => :check_boxes, :collection => Photographer.find(:all) %>
    <% end %>
   
    <%# f.inputs :name => 'Zdjęcia do Artykułu', :id => 'photos' do %>
       <%#= f.render_associated_form :photos, :partial => 'articles/photo', :f => f %>
       <%#= f.add_associated_link "+", :photos, :partial => 'articles/photo', :f => f %>
    <%# end %>

  
<%= f.render_associated_form(@article.photos, :new => 2) %>
<%= f.add_associated_link('Add another photo', @article.photos.build) %> <% f.buttons do %> <%= f.commit_button :label => "Zapisz" %> <% end %> <% end %>
[/code]

partial _photo:

[code]<%#

%>
<%#= f.input :description %>
<%#= f.input :file, :as => :file %>
<%#= f.remove_link “Usuń” %>
<%#
%>

Description: <%= f.text_field :description %>

Photo:
<%= f.file_field :file %>

<%= f.remove_link “remove” %>

[/code] Korzystam z tutoriala na stronie: [url=http://www.mfischer.com/wordpress/2009/02/02/multiple-image-upload-and-crop-with-rails/]Multiple image upload and crop with Rails[/url]

W widoku oraz partialu są zakomentowane pewne części formularza które niestety nie działają wątek juz uruchomilem wczoraj na forum: formtastic i attribute_fu problem

po pierwsze wywal cały formularz z tagu


a po tej linijce

@photo.user_id = current_user.id if current_user

daj sobie

logger.info current_user.inspect

I zobacz czy jest to samo co w widoku. Powinno być.
Zobacz też w konsoli czy możesz fotografii przypisać id usera.

ruby script/console photo = Photo.find(:first, :order=>'created_at DESC') user = User.find(1) photo.user_id = user.id photo.save

To może głupia uwaga, ale formularz który podałeś wywołuje tylko akcję create z kontrolera ArticlesController, w którym nie przypisujesz usera żadnym zdjęciom. Czyli jeśli tworzysz artykuł dodając od razu zdjęcia, to nie będą one miały przypisanego usera.

true

nie wziąłem pod uwagę tego, że to zagnieżdżone formularze i akcja z photos controllera w ogóle się nie wykonuje
więc możesz to zrobić tak
w articles controller

@article.photos.each do |photo| photo.user_id = current_user.id photo.save end
po linijce

  if @article.save

Tak masz racje ale to też nic nie pomogło dalej błąd:

[code]ActiveRecord::StatementInvalid in ArticlesController#create

Mysql::Error: Column ‘user_id’ cannot be null: INSERT INTO photos (created_at, file_content_type, file_file_size, updated_at, file_file_name, article_id, user_id, description) VALUES(‘2010-08-30 14:31:49’, ‘image/jpeg’, 44739, ‘2010-08-30 14:31:49’, ‘folder.jpg’, 45, NULL, ‘vcxvxc232’)[/code]

a ja bym poprosił najpierw o to co jest zapisane w modelu a nie w controllerze ^^

a tak w ogole, jezeli nie jestes pewny czy to current_user.id jest poprawne… wpisz tam na sztywno np… 2 i zobacz czy przejdzie

Na sztywno też nie przeszło:
daje modele:
article

belongs_to :user has_many :photos, :attributes => true, :discard_if => proc { |photo| photo.file_file_size.nil? }
user

has_many :articles has_many :photos
photo

belongs_to :article belongs_to :user has_attached_file :file, :styles => { :thumb => ["100x100#", :jpg], :pagesize => ["500x400", :jpg], }, :default_style => :pagesize

W konsoli jak chcę dodać user_id do tabeli photos niestedy przy zapisie pojawia się false czyli że nie zapisuje. Z poziomu bazy danych taki zapis jest możliwy bo sprawdziłem. W konsoli przy wywolaniu photo.save! zgłasza wyjątek:

[code]The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.
/usr/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:162:in interpolate_without_deprecated_syntax' e[4;36;1mSQL (0.2ms)e[0m e[0;1mROLLBACKe[0m /usr/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:157:ingsub’
/usr/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:157:in interpolate_without_deprecated_syntax' ActiveRecord::RecordInvalid: Negatywne sprawdzenie poprawności: File content type is not one of image/jpeg, image/pjpeg, image/jpg /usr/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:197:inpreserve_encoding’
from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:1090:in save_without_dirty!' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:87:insave_without_transactions!’
/usr/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:156:in interpolate_without_deprecated_syntax' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/i18n_interpolation_deprecation.rb:21:ininterpolate’
from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in save!' /usr/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:49:intranslate’
/usr/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n.rb:152:in translate' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:intransaction’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:116:in generate_full_message' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:intransaction’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:36:in full_message' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:275:infull_messages’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:275:in map' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:275:infull_messages’
from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in save!' (irb):8:ininject’
from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:208:in rollback_active_record_state!' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:274:ineach’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:274:in inject' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:274:infull_messages’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:13:in initialize' from /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:insave!’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:1090:in new' from (irb):8 /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:1090:insave_without_dirty!’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:87:in save_without_transactions!' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:insave!’

/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in transaction' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:intransaction’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in save!' /usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:208:inrollback_active_record_state!’
/usr/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in save!' (irb):8:inirb_binding’
/usr/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding’
/usr/lib/ruby/1.8/irb/workspace.rb:52[/code]
Pomóżcie bo zwariuję :slight_smile:

błąd o którym piszesz związany jest troszkę z tym że po wersji gemika I18n 0.4.0 zmienili sposób wywołania metody tak więc rodzi to kilka dodatkowych pytań

jakie gemy masz w systemie (wersje i18n dokładnie nas interesują)
ta aplikacja jest w rails 2.3.5 ?
czy w systemie masz też gem rails 3
czy uzywasz rvm-a

blad ten wynika z uzywania gemu i18n… a nie wbudowanego modułu I18n we wczesniejszych wersjach rails (niż rails 3)

fix na szybko który powinien zadziałać, jeżeli nie używasz rails 3 to usunąć gem I18n

a tu coś więcej

Witam, dzięki pirat faktycznie po odinstalowaniu gema I18n wszystko chodzi tak jak należy.